From 5dbf91c671aab085c434b31691039c85787ceef1 Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Fri, 21 May 2004 04:01:30 +0000 Subject: [PATCH] Previous copy failed; delete for new copy --- src/volser/.cvsignore | 11 - src/volser/Makefile.in | 211 -- src/volser/NTMakefile | 168 - src/volser/common.c | 66 - src/volser/dump.h | 52 - src/volser/dumpstuff.c | 1637 ---------- src/volser/lockdata.h | 30 - src/volser/lockprocs.c | 261 -- src/volser/physio.c | 176 - src/volser/restorevol.c | 993 ------ src/volser/vol.h | 26 - src/volser/volerr.et | 32 - src/volser/volint.xg | 410 --- src/volser/volmain.c | 458 --- src/volser/volprocs.c | 2908 ----------------- src/volser/volser.p.h | 172 - src/volser/volserver.rc | 17 - src/volser/voltrans.c | 228 -- src/volser/vos.c | 5593 ------------------------------- src/volser/vos.rc | 17 - src/volser/vsprocs.c | 6880 --------------------------------------- src/volser/vsutils.c | 674 ---- 22 files changed, 21020 deletions(-) delete mode 100644 src/volser/.cvsignore delete mode 100644 src/volser/Makefile.in delete mode 100644 src/volser/NTMakefile delete mode 100644 src/volser/common.c delete mode 100644 src/volser/dump.h delete mode 100644 src/volser/dumpstuff.c delete mode 100644 src/volser/lockdata.h delete mode 100644 src/volser/lockprocs.c delete mode 100644 src/volser/physio.c delete mode 100644 src/volser/restorevol.c delete mode 100644 src/volser/vol.h delete mode 100644 src/volser/volerr.et delete mode 100644 src/volser/volint.xg delete mode 100644 src/volser/volmain.c delete mode 100644 src/volser/volprocs.c delete mode 100644 src/volser/volser.p.h delete mode 100644 src/volser/volserver.rc delete mode 100644 src/volser/voltrans.c delete mode 100644 src/volser/vos.c delete mode 100644 src/volser/vos.rc delete mode 100644 src/volser/vsprocs.c delete mode 100644 src/volser/vsutils.c diff --git a/src/volser/.cvsignore b/src/volser/.cvsignore deleted file mode 100644 index 8d0ac8660..000000000 --- a/src/volser/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -AFS_component_version_number.c -Makefile -restorevol -volerr.c -volint.cs.c -volint.h -volint.ss.c -volint.xdr.c -volser.h -volserver -vos diff --git a/src/volser/Makefile.in b/src/volser/Makefile.in deleted file mode 100644 index 7833d7802..000000000 --- a/src/volser/Makefile.in +++ /dev/null @@ -1,211 +0,0 @@ -# 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 - -srcdir=@srcdir@ -include @TOP_OBJDIR@/src/config/Makefile.config -HELPER_SPLINT=@HELPER_SPLINT@ - - -VINCLS=${TOP_INCDIR}/afs/partition.h ${TOP_INCDIR}/afs/volume.h \ - ${TOP_INCDIR}/afs/vlserver.h vol.h dump.h volser.h lockdata.h - -RINCLS=${TOP_INCDIR}/rx/rx.h ${TOP_INCDIR}/rx/xdr.h \ - ${TOP_INCDIR}/afs/keys.h ${TOP_INCDIR}/afs/cellconfig.h \ - ${TOP_INCDIR}/ubik.h ${TOP_INCDIR}/afs/cmd.h - -INTINCLS=volint.h volser.h - -LIBS=\ - ${TOP_LIBDIR}/libaudit.a \ - ${TOP_LIBDIR}/vlib.a \ - ${TOP_LIBDIR}/libacl.a \ - ${TOP_LIBDIR}/libsys.a \ - ${TOP_LIBDIR}/libvldb.a \ - ${TOP_LIBDIR}/libubik.a \ - ${TOP_LIBDIR}/libauth.a \ - ${TOP_LIBDIR}/libcmd.a \ - ${TOP_LIBDIR}/librxkad.a \ - ${TOP_LIBDIR}/libdes.a \ - ${TOP_LIBDIR}/librxstat.a \ - ${TOP_LIBDIR}/librx.a \ - ${TOP_LIBDIR}/liblwp.a \ - ${TOP_LIBDIR}/libsys.a \ - ${TOP_LIBDIR}/libcom_err.a \ - ${TOP_LIBDIR}/libkauth.a \ - ${TOP_LIBDIR}/libusd.a \ - ${TOP_LIBDIR}/util.a - -VOLDUMP_LIBS = \ - ../vol/ihandle.o \ - ../vol/physio.o \ - ../vol/vlib.a \ - ${TOP_LIBDIR}/libcmd.a \ - ${TOP_LIBDIR}/util.a \ - ${TOP_LIBDIR}/libsys.a \ - ${TOP_LIBDIR}/libdir.a \ - ${TOP_LIBDIR}/liblwp.a \ - ${TOP_LIBDIR}/libacl.a - -VSOBJS=vsprocs.o vsutils.o lockprocs.o volint.xdr.o volerr.o -SOBJS=volmain.o volprocs.o physio.o common.o voltrans.o volerr.o \ - volint.cs.o dumpstuff.o volint.ss.o volint.xdr.o - -all: volserver vos restorevol voldump \ - ${TOP_INCDIR}/afs/volser.h \ - ${TOP_INCDIR}/afs/volint.h \ - ${TOP_LIBDIR}/libvolser.a - -restorevol: restorevol.c - ${CC} ${CFLAGS} -o restorevol ${srcdir}/restorevol.c \ - ${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/util.a ${XLIBS} - -vos: vos.o ${VSOBJS} libvolser.a ${LIBS} - ${CC} ${LDFLAGS} -o vos vos.o $(VSOBJS) libvolser.a ${LIBS} ${XLIBS} - -volserver: $(SOBJS) $(LIBS) ${TOP_LIBDIR}/libdir.a - ${CC} ${DBUG} -o volserver $(SOBJS) ${TOP_LIBDIR}/libdir.a \ - ${LDFLAGS} $(LIBS) ${XLIBS} - -voldump: vol-dump.o ${VOLDUMP_LIBS} - ${CC} ${CFLAGS} -o voldump vol-dump.o ${VOLDUMP_LIBS} ${XLIBS} - -libvolser.a: volint.cs.o $(VSOBJS) volint.ss.o AFS_component_version_number.o - -$(RM) -f $@ - $(AR) crv $@ volint.cs.o $(VSOBJS) volint.ss.o AFS_component_version_number.o - $(RANLIB) $@ - -volser.h volerr.c: volerr.et volser.p.h - $(RM) -f volser.h volerr.c - ${COMPILE_ET} -p ${srcdir} volerr -h volser - -volint.cs.c: volint.xg - ${RXGEN} -x -C -o $@ ${srcdir}/volint.xg - -volint.ss.c: volint.xg - ${RXGEN} -x -S -o $@ ${srcdir}/volint.xg - -volint.xdr.c: volint.xg - ${RXGEN} -x -c -o $@ ${srcdir}/volint.xg - -volint.h: volint.xg - ${RXGEN} -x -h -o $@ ${srcdir}/volint.xg - -volint.cs.c: volint.h -volint.ss.c: volint.h -volint.xdr.c: volint.h - -# -# Dependencies -# -volint.cs.o: volint.cs.c ${INTINCLS} -volint.ss.o: volint.ss.c ${INTINCLS} -volint.xdr.o: volint.xdr.c ${INTINCLS} -vsutils.o: vsutils.c ${VINCLS} ${RINCLS} ${INTINCLS} -volmain.o: volmain.c ${VINCLS} ${RINCLS} AFS_component_version_number.c -volprocs.o: volprocs.c ${VINCLS} ${RINCLS} ${INTINCLS} -dumpstuff.o: dumpstuff.c ${VINCLS} ${RINCLS} ${INTINCLS} -voldump.o: voldump.c ${VINCLS} ${RINCLS} -vos.o: vos.c ${VINCLS} ${RINCLS} ${INTINCLS} AFS_component_version_number.c -vsprocs.o: vsprocs.c ${VINCLS} ${RINCLS} ${INTINCLS} -physio.o: physio.c ${VINCLS} -common.o: common.c ${VINCLS} -lockprocs.o: lockprocs.c ${VINCLS} ${INTINCLS} ${RINCLS} - -# -# Installation targets -# -install: \ - ${DESTDIR}${sbindir}/restorevol \ - ${DESTDIR}${sbindir}/voldump \ - ${DESTDIR}${includedir}/afs/volser.h \ - ${DESTDIR}${includedir}/afs/volint.h \ - ${DESTDIR}${sbindir}/vos \ - ${DESTDIR}${afssrvsbindir}/vos \ - ${DESTDIR}${afssrvlibexecdir}/volserver \ - ${DESTDIR}${libdir}/afs/libvolser.a - - -${DEST}/include/afs/volser.h: volser.h - ${INSTALL} $? $@ - -${DEST}/include/afs/volint.h: volint.h - ${INSTALL} $? $@ - -${DEST}/etc/restorevol: restorevol - ${INSTALL} $? $@ - -${DEST}/etc/voldump: voldump - ${INSTALL} $? $@ - -${DEST}/etc/vos ${DEST}/root.server/usr/afs/bin/vos: vos - ${INSTALL} $? $@ - -${DEST}/lib/afs/libvolser.a: libvolser.a - ${INSTALL} $? $@ - -${DEST}/root.server/usr/afs/bin/volserver: volserver - ${INSTALL} $? $@ - -# -# Misc targets -# -clean: - $(RM) -f *.o *.a core volserver volint.ss.c volint.cs.c volint.h \ - volint.xdr.c vos volser.h volerr.c AFS_component_version_number.c restorevol voldump - -include ../config/Makefile.version - -${DESTDIR}${sbindir}/restorevol: restorevol - ${INSTALL} $? $@ - -${DESTDIR}${sbindir}/voldump: voldump - ${INSTALL} $? $@ - -${DESTDIR}${includedir}/afs/volser.h: volser.h - ${INSTALL} $? $@ - -${TOP_INCDIR}/afs/volser.h: volser.h - ${INSTALL} $? $@ - -${DESTDIR}${includedir}/afs/volint.h: volint.h - ${INSTALL} $? $@ - -${TOP_INCDIR}/afs/volint.h: volint.h - ${INSTALL} $? $@ - -${DESTDIR}${sbindir}/vos: vos - ${INSTALL} $? $@ - -${DESTDIR}${afssrvsbindir}/vos: vos - ${INSTALL} $? $@ - -${DESTDIR}${afssrvlibexecdir}/volserver: volserver - ${INSTALL} $? $@ - -${DESTDIR}${libdir}/afs/libvolser.a: libvolser.a - ${INSTALL} $? $@ - -${TOP_LIBDIR}/libvolser.a: libvolser.a - ${INSTALL} $? $@ - -dest: \ - ${DEST}/etc/restorevol \ - ${DEST}/etc/voldump \ - ${DEST}/include/afs/volser.h \ - ${DEST}/include/afs/volint.h \ - ${DEST}/etc/vos \ - ${DEST}/root.server/usr/afs/bin/vos \ - ${DEST}/root.server/usr/afs/bin/volserver \ - ${DEST}/lib/afs/libvolser.a - - -check-splint:: - sh $(HELPER_SPLINT) $(CFLAGS) \ - vos.c restorevol.c \ - vsprocs.c vsutils.c lockprocs.c volerr.c \ - volmain.c volprocs.c physio.c common.c voltrans.c \ - dumpstuff.c diff --git a/src/volser/NTMakefile b/src/volser/NTMakefile deleted file mode 100644 index ff0e91446..000000000 --- a/src/volser/NTMakefile +++ /dev/null @@ -1,168 +0,0 @@ -# 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 - -RELDIR=volser -!INCLUDE ..\config\NTMakefile.$(SYS_NAME) -!INCLUDE ..\config\NTMakefile.version - -############################################################################ -# Definitions for installing header files - -INCFILEDIR = $(DESTDIR)\include\afs # header file install directory - -INCFILES = \ - $(INCFILEDIR)\volser_prototypes.h \ - $(INCFILEDIR)\volser.h \ - $(INCFILEDIR)\volint.h - - -LOCAL_INCFILES = \ - volser.h \ - volint.h - -############################################################################ -# Build volser library. - -LIBFILE = $(DESTDIR)\lib\afs\afsvolser.lib - -LIBOBJS =\ - $(OUT)\lockprocs.obj \ - $(OUT)\volerr.obj \ - $(OUT)\volint.cs.obj \ - $(OUT)\volint.ss.obj \ - $(OUT)\volint.xdr.obj \ - $(OUT)\vsprocs.obj \ - $(OUT)\vsutils.obj \ - $(OUT)\AFS_component_version_number.obj - -$(LIBFILE): $(LIBOBJS) - $(LIBARCH) - - -############################################################################ -# External libraries - -EXEC_LIBS = \ - $(DESTDIR)\lib\afs\afscmd.lib \ - $(DESTDIR)\lib\afs\afsvol.lib \ - $(DESTDIR)\lib\afs\afsutil.lib \ - $(DESTDIR)\lib\afs\afsdir.lib \ - $(DESTDIR)\lib\afs\afsvol.lib \ - $(DESTDIR)\lib\afs\afsaudit.lib \ - $(DESTDIR)\lib\afs\afsauth.lib \ - $(DESTDIR)\lib\afs\afsvldb.lib \ - $(DESTDIR)\lib\afs\afskauth.lib \ - $(DESTDIR)\lib/afs/afscom_err.lib \ - $(DESTDIR)\lib\afs\afsusd.lib \ - $(DESTDIR)\lib\afsrxkad.lib \ - $(DESTDIR)\lib\afsrxstat.lib \ - $(DESTDIR)\lib\afsdes.lib \ - $(DESTDIR)\lib\afsrx.lib \ - $(DESTDIR)\lib\afslwp.lib \ - $(DESTDIR)\lib\afs\afsacl.lib \ - $(DESTDIR)\lib\afs\afsreg.lib \ - $(DESTDIR)\lib\afs\afseventlog.lib \ - $(DESTDIR)\lib\cm_dns.obj - - -############################################################################ -# Build volserver - -VOLSERVER_EXEFILE = $(DESTDIR)\root.server\usr\afs\bin\volserver.exe - -VOLSERVER_EXEOBJS = \ - $(OUT)\common.obj \ - $(OUT)\dumpstuff.obj \ - $(OUT)\physio.obj \ - $(OUT)\volerr.obj \ - $(OUT)\volint.cs.obj \ - $(OUT)\volint.ss.obj \ - $(OUT)\volint.xdr.obj \ - $(OUT)\volmain.obj \ - $(OUT)\volprocs.obj \ - $(OUT)\voltrans.obj \ - $(OUT)\volserver.res - - -VOLSERVER_EXELIBS = \ - $(DESTDIR)\lib\afs\afsdir.lib \ - $(DESTDIR)\lib\afs\afsprocmgmt.lib - -$(VOLSERVER_EXEFILE): $(VOLSERVER_EXEOBJS) $(VOLSERVER_EXELIBS) $(EXEC_LIBS) - $(EXECONLINK) - $(EXEPREP) - -############################################################################ -# Build vos - -RS_VOS_EXEFILE = $(DESTDIR)\root.server\usr\afs\bin\vos.exe -CL_VOS_EXEFILE = $(DESTDIR)\etc\vos.exe - -VOS_EXEOBJS = \ - $(OUT)\vos.obj \ - $(OUT)\vsprocs.obj \ - $(OUT)\vsutils.obj \ - $(OUT)\lockprocs.obj \ - $(OUT)\volint.xdr.obj \ - $(OUT)\volerr.obj \ - $(OUT)\vos.res - -VOS_EXELIBS = \ - $(DESTDIR)\lib\afsubik.lib \ - $(DESTDIR)\lib\afs\afsvolser.lib \ - $(DESTDIR)\lib\afs\afsprocmgmt.lib \ - $(DESTDIR)\lib\afs\afspioctl.lib - -$(RS_VOS_EXEFILE): $(VOS_EXEOBJS) $(VOS_EXELIBS) $(EXEC_LIBS) - $(EXECONLINK) - $(EXEPREP) - -$(CL_VOS_EXEFILE): $(RS_VOS_EXEFILE) - $(COPY) $** $@ - -############################################################################ -# Generate versioninfo resources -$(OUT)\volserver.res: AFS_component_version_number.h - -$(OUT)\vos.res: AFS_component_version_number.h - -############################################################################ -# Definitions for generating files via RXGEN - -$(INCFILES):$$(@F) - $(COPY) $** $(INCFILEDIR)\. - -volint.h volint.cs.c volint.ss.c volint.xdr.c: volint.xg - $(RXGEN) -x $** - - -############################################################################ -# Definitions for generating files via COMPILE_ET - -volser.h volerr.c: volerr.et volser.p.h - $(DEL) volerr.c volser.h - $(COMPILE_ET) volerr -h volser - - - - -############################################################################ -# Install target; primary makefile target - -install: $(LOCAL_INCFILES) $(LIBFILE) $(VOLSERVER_EXEFILE) $(CL_VOS_EXEFILE) \ - $(INCFILES) - - -############################################################################ -# Local clean target; augments predefined clean target - -clean:: - $(DEL) volerr.c volser.h $(INCFILES) - $(DEL) volint.cs.c volint.h volint.ss.c volint.xdr.c volser.h - -mkdir: - diff --git a/src/volser/common.c b/src/volser/common.c deleted file mode 100644 index 1af526e63..000000000 --- a/src/volser/common.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/common.c,v 1.10 2003/11/15 04:59:16 shadow Exp $"); - -#include -#include -#include - -#ifndef AFS_PTHREAD_ENV -/*@printflike@*/ void -Log(const char *format, ...) -{ - va_list args; - - va_start(args, format); - vViceLog(0, (format, args)); - va_end(args); -} -#endif - -void -LogError(afs_int32 errcode) -{ - ViceLog(0, - ("%s: %s\n", error_table_name(errcode), error_message(errcode))); -} - -#ifndef AFS_PTHREAD_ENV -/*@printflike@*/ void -Abort(const char *format, ...) -{ - va_list args; - - ViceLog(0, ("Program aborted: ")); - va_start(args, format); - vViceLog(0, (format, args)); - va_end(args); - abort(); -} -#endif - -void -InitErrTabs(void) -{ -#ifndef AFS_PTHREAD_ENV - initialize_KA_error_table(); - initialize_RXK_error_table(); - initialize_KTC_error_table(); - initialize_ACFG_error_table(); - initialize_CMD_error_table(); - initialize_VL_error_table(); - initialize_VOLS_error_table(); -#endif - return; -} diff --git a/src/volser/dump.h b/src/volser/dump.h deleted file mode 100644 index 349eb7247..000000000 --- a/src/volser/dump.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 - */ - -/* - System: Volser - Module: dump.h - Institution: The Information Technology Center, Carnegie-Mellon University - - */ - -#define DUMPVERSION 1 - -#define DUMPENDMAGIC 0x3A214B6E -#define DUMPBEGINMAGIC 0xB3A11322 - -#define D_DUMPHEADER 1 -#define D_VOLUMEHEADER 2 -#define D_VNODE 3 -#define D_DUMPEND 4 - -#define D_MAX 20 - -#define MAXDUMPTIMES 50 - -/* DumpHeader: - Each {from,to} pair of time values gives a span of time covered by this dump. - Merged dumps may have multiple pairs if there are dumps missing from the merge */ - -struct DumpHeader { - afs_int32 version; - VolumeId volumeId; - char volumeName[VNAMESIZE]; - int nDumpTimes; /* Number of pairs */ - struct { - afs_int32 from, to; - } dumpTimes[MAXDUMPTIMES]; -}; - - -/* Some handshaking constants for volume move */ -#define SHAKE1 "x" -#define SHAKE2 "y" -#define SHAKE3 "z" -#define SHAKE4 "P" -#define SHAKE5 "Q" -#define SHAKE_ABORT "!" diff --git a/src/volser/dumpstuff.c b/src/volser/dumpstuff.c deleted file mode 100644 index 83562b200..000000000 --- a/src/volser/dumpstuff.c +++ /dev/null @@ -1,1637 +0,0 @@ -/* - * 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 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/dumpstuff.c,v 1.25 2003/11/23 04:53:44 jaltman Exp $"); - -#include -#include -#include -#include -#ifdef AFS_NT40_ENV -#include -#else -#include -#include -#include -#include -#include -#endif -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif -#include -#ifdef AFS_PTHREAD_ENV -#include -#else /* AFS_PTHREAD_ENV */ -#include -#endif /* AFS_PTHREAD_ENV */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dump.h" -#include -#include -#include "volser.h" -#include "volint.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, - afs_int32 fromtime); -static int DumpPartial(register struct iod *iodp, register Volume * vp, - afs_int32 fromtime, int dumpAllDirs); -static int DumpVnodeIndex(register struct iod *iodp, Volume * vp, - VnodeClass class, afs_int32 fromtime, - int forcedump); -static int DumpVnode(register struct iod *iodp, struct VnodeDiskObject *v, - int volid, int vnodeNumber, int dumpEverything); -static int ReadDumpHeader(register struct iod *iodp, struct DumpHeader *hp); -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 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, - 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) -{ - iodp->call = call; - iodp->haveOldChar = 0; - iodp->ncalls = 1; - iodp->calls = (struct rx_call **)0; -} - -static void -iod_InitMulti(struct iod *iodp, struct rx_call **calls, int ncalls, - int *codes) -{ - - iodp->calls = calls; - iodp->haveOldChar = 0; - iodp->ncalls = ncalls; - iodp->codes = codes; - iodp->call = (struct rx_call *)0; -} - -/* N.B. iod_Read doesn't check for oldchar (see previous comment) */ -#define iod_Read(iodp, buf, nbytes) rx_Read((iodp)->call, buf, nbytes) - -/* For the single dump case, it's ok to just return the "bytes written" - * that rx_Write returns, since all the callers of iod_Write abort when - * the returned value is less than they expect. For the multi dump case, - * I don't think we want half the replicas to go bad just because one - * connection timed out, but if they all time out, then we should give up. - */ -static int -iod_Write(struct iod *iodp, char *buf, int nbytes) -{ - int code, i; - int one_success = 0; - - assert((iodp->call && iodp->ncalls == 1 && !iodp->calls) - || (!iodp->call && iodp->ncalls >= 1 && iodp->calls)); - - if (iodp->call) { - code = rx_Write(iodp->call, buf, nbytes); - return code; - } - - for (i = 0; i < iodp->ncalls; i++) { - if (iodp->calls[i] && !iodp->codes[i]) { - code = rx_Write(iodp->calls[i], buf, nbytes); - if (code != nbytes) { /* everything gets merged into a single error */ - iodp->codes[i] = VOLSERDUMPERROR; /* but that's exactly what the */ - } /* standard dump does, anyways */ - else { - one_success = TRUE; - } - } - } /* for all calls */ - - if (one_success) - return nbytes; - else - return 0; -} - -static void -iod_ungetc(struct iod *iodp, int achar) -{ - iodp->oldChar = achar; - iodp->haveOldChar = 1; -} - -static int -iod_getc(register struct iod *iodp) -{ - unsigned char t; - - if (iodp->haveOldChar) { - iodp->haveOldChar = 0; - return iodp->oldChar; - } - if (iod_Read(iodp, &t, 1) == 1) - return t; - return EOF; -} - -static int -ReadShort(register struct iod *iodp, register unsigned short *sp) -{ - register b1, b0; - b1 = iod_getc(iodp); - b0 = iod_getc(iodp); - *sp = (b1 << 8) | b0; - return b0 != EOF; -} - -static int -ReadInt32(register struct iod *iodp, afs_uint32 * lp) -{ - afs_uint32 register b3, b2, b1, b0; - b3 = iod_getc(iodp); - b2 = iod_getc(iodp); - b1 = iod_getc(iodp); - b0 = iod_getc(iodp); - *lp = (((((b3 << 8) | b2) << 8) | b1) << 8) | b0; - return b0 != EOF; -} - -static void -ReadString(register struct iod *iodp, register char *to, register int maxa) -{ - register int c; - while (maxa--) { - if ((*to++ = iod_getc(iodp)) == 0) - break; - } - if (to[-1]) { - while ((c = iod_getc(iodp)) && c != EOF); - to[-1] = 0; - } -} - -static void -ReadByteString(register struct iod *iodp, register byte * to, - register int size) -{ - while (size--) - *to++ = iod_getc(iodp); -} - -static int -ReadVolumeHeader(register struct iod *iodp, VolumeDiskData * vol) -{ - register tag; - afs_uint32 trash; - memset(vol, 0, sizeof(*vol)); - while ((tag = iod_getc(iodp)) > D_MAX && tag != EOF) { - switch (tag) { - case 'i': - if (!ReadInt32(iodp, &vol->id)) - return VOLSERREAD_DUMPERROR; - break; - case 'v': - if (!ReadInt32(iodp, &trash)) - return VOLSERREAD_DUMPERROR; - break; - case 'n': - ReadString(iodp, vol->name, sizeof(vol->name)); - /*this means the name of the retsored volume could be possibly different. In conjunction with SAFSVolSignalRestore */ - break; - case 's': - vol->inService = iod_getc(iodp); - break; - case 'b': - vol->blessed = iod_getc(iodp); - break; - case 'u': - if (!ReadInt32(iodp, &vol->uniquifier)) - return VOLSERREAD_DUMPERROR; - break; - case 't': - vol->type = iod_getc(iodp); - break; - case 'p': - if (!ReadInt32(iodp, &vol->parentId)) - return VOLSERREAD_DUMPERROR; - break; - case 'c': - if (!ReadInt32(iodp, &vol->cloneId)) - return VOLSERREAD_DUMPERROR; - break; - case 'q': - if (!ReadInt32(iodp, (afs_uint32 *) & vol->maxquota)) - return VOLSERREAD_DUMPERROR; - break; - case 'm': - if (!ReadInt32(iodp, (afs_uint32 *) & vol->minquota)) - return VOLSERREAD_DUMPERROR; - break; - case 'd': - if (!ReadInt32(iodp, (afs_uint32 *) & vol->diskused)) - return VOLSERREAD_DUMPERROR; /* Bogus: should calculate this */ - break; - case 'f': - if (!ReadInt32(iodp, (afs_uint32 *) & vol->filecount)) - return VOLSERREAD_DUMPERROR; - break; - case 'a': - if (!ReadInt32(iodp, &vol->accountNumber)) - return VOLSERREAD_DUMPERROR; - break; - case 'o': - if (!ReadInt32(iodp, &vol->owner)) - return VOLSERREAD_DUMPERROR; - break; - case 'C': - if (!ReadInt32(iodp, &vol->creationDate)) - return VOLSERREAD_DUMPERROR; - break; - case 'A': - if (!ReadInt32(iodp, &vol->accessDate)) - return VOLSERREAD_DUMPERROR; - break; - case 'U': - if (!ReadInt32(iodp, &vol->updateDate)) - return VOLSERREAD_DUMPERROR; - break; - case 'E': - if (!ReadInt32(iodp, &vol->expirationDate)) - return VOLSERREAD_DUMPERROR; - break; - case 'B': - if (!ReadInt32(iodp, &vol->backupDate)) - return VOLSERREAD_DUMPERROR; - break; - case 'O': - ReadString(iodp, vol->offlineMessage, - sizeof(vol->offlineMessage)); - break; - case 'M': - /* - * Detailed volume statistics are never stored in dumps, - * so we just restore either the null string if this volume - * had already been set to store statistics, or the old motd - * contents otherwise. It doesn't matter, since this field - * will soon get initialized anyway. - */ - ReadString(iodp, (char *)(vol->stat_reads), VMSGSIZE); - break; - case 'W':{ - unsigned short length; - int i; - afs_uint32 data; - if (!ReadShort(iodp, &length)) - return VOLSERREAD_DUMPERROR; - for (i = 0; i < length; i++) { - if (!ReadInt32(iodp, &data)) - return VOLSERREAD_DUMPERROR; - if (i < sizeof(vol->weekUse) / sizeof(vol->weekUse[0])) - vol->weekUse[i] = data; - } - break; - } - case 'D': - if (!ReadInt32(iodp, &vol->dayUseDate)) - return VOLSERREAD_DUMPERROR; - break; - case 'Z': - if (!ReadInt32(iodp, (afs_uint32 *) & vol->dayUse)) - return VOLSERREAD_DUMPERROR; - break; - } - } - iod_ungetc(iodp, tag); - return 0; -} - -static int -DumpTag(register struct iod *iodp, register int tag) -{ - char p; - - p = tag; - return ((iod_Write(iodp, &p, 1) == 1) ? 0 : VOLSERDUMPERROR); - -} - -static int -DumpByte(register struct iod *iodp, char tag, byte value) -{ - char tbuffer[2]; - register byte *p = (unsigned char *)tbuffer; - *p++ = tag; - *p = value; - return ((iod_Write(iodp, tbuffer, 2) == 2) ? 0 : VOLSERDUMPERROR); -} - -#define putint32(p, v) *p++ = v>>24, *p++ = v>>16, *p++ = v>>8, *p++ = v -#define putshort(p, v) *p++ = v>>8, *p++ = v - -static int -DumpDouble(register struct iod *iodp, char tag, register afs_uint32 value1, - register afs_uint32 value2) -{ - char tbuffer[9]; - register byte *p = (unsigned char *)tbuffer; - *p++ = tag; - putint32(p, value1); - putint32(p, value2); - return ((iod_Write(iodp, tbuffer, 9) == 9) ? 0 : VOLSERDUMPERROR); -} - -static int -DumpInt32(register struct iod *iodp, char tag, register afs_uint32 value) -{ - char tbuffer[5]; - register byte *p = (unsigned char *)tbuffer; - *p++ = tag; - putint32(p, value); - return ((iod_Write(iodp, tbuffer, 5) == 5) ? 0 : VOLSERDUMPERROR); -} - -static int -DumpArrayInt32(register struct iod *iodp, char tag, - register afs_uint32 * array, register int nelem) -{ - char tbuffer[4]; - register afs_uint32 v; - int code = 0; - register byte *p = (unsigned char *)tbuffer; - *p++ = tag; - putshort(p, nelem); - code = iod_Write(iodp, tbuffer, 3); - if (code != 3) - return VOLSERDUMPERROR; - while (nelem--) { - p = (unsigned char *)tbuffer; - v = *array++; /*this was register */ - - putint32(p, v); - code = iod_Write(iodp, tbuffer, 4); - if (code != 4) - return VOLSERDUMPERROR; - } - return 0; -} - -static int -DumpShort(register struct iod *iodp, char tag, unsigned int value) -{ - char tbuffer[3]; - register byte *p = (unsigned char *)tbuffer; - *p++ = tag; - *p++ = value >> 8; - *p = value; - return ((iod_Write(iodp, tbuffer, 3) == 3) ? 0 : VOLSERDUMPERROR); -} - -static int -DumpBool(register struct iod *iodp, char tag, unsigned int value) -{ - char tbuffer[2]; - register byte *p = (unsigned char *)tbuffer; - *p++ = tag; - *p = value; - return ((iod_Write(iodp, tbuffer, 2) == 2) ? 0 : VOLSERDUMPERROR); -} - -static int -DumpString(register struct iod *iodp, char tag, register char *s) -{ - register n; - int code = 0; - code = iod_Write(iodp, &tag, 1); - if (code != 1) - return VOLSERDUMPERROR; - n = strlen(s) + 1; - code = iod_Write(iodp, s, n); - if (code != n) - return VOLSERDUMPERROR; - return 0; -} - -static int -DumpByteString(register struct iod *iodp, char tag, register byte * bs, - register int nbytes) -{ - int code = 0; - - code = iod_Write(iodp, &tag, 1); - if (code != 1) - return VOLSERDUMPERROR; - code = iod_Write(iodp, (char *)bs, nbytes); - if (code != nbytes) - return VOLSERDUMPERROR; - return 0; -} - -static int -DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP) -{ - int code = 0, lcode = 0, error = 0; - afs_int32 pad = 0, offset; - afs_sfsize_t n, nbytes, howMany, howBig; - byte *p; -#ifndef AFS_NT40_ENV - struct afs_stat status; -#endif - afs_sfsize_t size; -#ifdef AFS_AIX_ENV -#include - struct statfs tstatfs; -#endif - -#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); -#ifdef AFS_LARGEFILE_ENV - { - afs_uint32 hi, lo; - SplitInt64(size, hi, lo); - if (hi == 0L) { - code = DumpInt32(iodp, 'f', lo); - } else { - code = DumpDouble(iodp, 'h', hi, lo); - } - } -#else /* !AFS_LARGEFILE_ENV */ - code = DumpInt32(iodp, 'f', size); -#endif /* !AFS_LARGEFILE_ENV */ - if (code) { - return VOLSERDUMPERROR; - } - - p = (unsigned char *)malloc(howMany); - if (!p) { - Log("1 Volser: DumpFile: no memory"); - return VOLSERDUMPERROR; - } - - for (nbytes = size; (nbytes && !error); nbytes -= howMany) { - if (nbytes < howMany) - howMany = nbytes; - - /* Read the data - unless we know we can't */ - n = (lcode ? 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) { - Log("1 Volser: DumpFile: 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) { - /* 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); - } else if (!pad) { - Log("1 Volser: DumpFile: 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. - */ - lcode = FDH_SEEK(handleP, ((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); - } else { - Log("1 Volser: DumpFile: Error seeking in inode %s for vnode %d\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode); - lcode = -1; - } - } else { - lcode = 0; - } - } - - /* Now write the data out */ - if (iod_Write(iodp, (char *)p, howMany) != howMany) - error = VOLSERDUMPERROR; -#ifndef AFS_PTHREAD_ENV - IOMGR_Poll(); -#endif - } - - if (pad) { /* Any padding we hadn't reported yet */ - Log("1 Volser: DumpFile: Null padding file: %d bytes at offset %u\n", - pad, offset); - } - - free(p); - return error; -} - -static int -DumpVolumeHeader(register struct iod *iodp, register Volume * vp) -{ - int code = 0; - static char nullString[1] = ""; /*The ``contents'' of motd */ - - if (!code) - code = DumpTag(iodp, D_VOLUMEHEADER); - if (!code) { - code = DumpInt32(iodp, 'i', V_id(vp)); - } - if (!code) - code = DumpInt32(iodp, 'v', V_stamp(vp).version); - if (!code) - code = DumpString(iodp, 'n', V_name(vp)); - if (!code) - code = DumpBool(iodp, 's', V_inService(vp)); - if (!code) - code = DumpBool(iodp, 'b', V_blessed(vp)); - if (!code) - code = DumpInt32(iodp, 'u', V_uniquifier(vp)); - if (!code) - code = DumpByte(iodp, 't', (byte) V_type(vp)); - if (!code) { - code = DumpInt32(iodp, 'p', V_parentId(vp)); - } - if (!code) - code = DumpInt32(iodp, 'c', V_cloneId(vp)); - if (!code) - code = DumpInt32(iodp, 'q', V_maxquota(vp)); - if (!code) - code = DumpInt32(iodp, 'm', V_minquota(vp)); - if (!code) - code = DumpInt32(iodp, 'd', V_diskused(vp)); - if (!code) - code = DumpInt32(iodp, 'f', V_filecount(vp)); - if (!code) - code = DumpInt32(iodp, 'a', V_accountNumber(vp)); - if (!code) - code = DumpInt32(iodp, 'o', V_owner(vp)); - if (!code) - code = DumpInt32(iodp, 'C', V_creationDate(vp)); /* Rw volume creation date */ - if (!code) - code = DumpInt32(iodp, 'A', V_accessDate(vp)); - if (!code) - code = DumpInt32(iodp, 'U', V_updateDate(vp)); - if (!code) - code = DumpInt32(iodp, 'E', V_expirationDate(vp)); - if (!code) - code = DumpInt32(iodp, 'B', V_backupDate(vp)); /* Rw volume backup clone date */ - if (!code) - code = DumpString(iodp, 'O', 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); - if (!code) - code = - DumpArrayInt32(iodp, 'W', (afs_uint32 *) V_weekUse(vp), - sizeof(V_weekUse(vp)) / sizeof(V_weekUse(vp)[0])); - if (!code) - code = DumpInt32(iodp, 'D', V_dayUseDate(vp)); - if (!code) - code = DumpInt32(iodp, 'Z', V_dayUse(vp)); - return code; -} - -static int -DumpEnd(register struct iod *iodp) -{ - return (DumpInt32(iodp, D_DUMPEND, DUMPENDMAGIC)); -} - -/* Guts of the dump code */ - -/* Dump a whole volume */ -int -DumpVolume(register struct rx_call *call, register Volume * vp, - afs_int32 fromtime, int dumpAllDirs) -{ - struct iod iod; - int code = 0; - register struct iod *iodp = &iod; - iod_Init(iodp, call); - - if (!code) - code = DumpDumpHeader(iodp, vp, fromtime); - - if (!code) - code = DumpPartial(iodp, vp, fromtime, dumpAllDirs); - -/* hack follows. Errors should be handled quite differently in this version of dump than they used to be.*/ - if (rx_Error(iodp->call)) { - Log("1 Volser: DumpVolume: Rx call failed during dump, error %d\n", - rx_Error(iodp->call)); - return VOLSERDUMPERROR; - } - if (!code) - code = DumpEnd(iodp); - - return code; -} - -/* Dump a volume to multiple places*/ -int -DumpVolMulti(struct rx_call **calls, int ncalls, Volume * vp, - afs_int32 fromtime, int dumpAllDirs, int *codes) -{ - struct iod iod; - int code = 0; - iod_InitMulti(&iod, calls, ncalls, codes); - - if (!code) - code = DumpDumpHeader(&iod, vp, fromtime); - if (!code) - code = DumpPartial(&iod, vp, fromtime, dumpAllDirs); - if (!code) - code = DumpEnd(&iod); - return code; -} - -/* A partial dump (no dump header) */ -static int -DumpPartial(register struct iod *iodp, register Volume * vp, - afs_int32 fromtime, int dumpAllDirs) -{ - int code = 0; - if (!code) - code = DumpVolumeHeader(iodp, vp); - if (!code) - code = DumpVnodeIndex(iodp, vp, vLarge, fromtime, dumpAllDirs); - if (!code) - code = DumpVnodeIndex(iodp, vp, vSmall, fromtime, 0); - return code; -} - -static int -DumpVnodeIndex(register struct iod *iodp, Volume * vp, VnodeClass class, - afs_int32 fromtime, int forcedump) -{ - 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 = - 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); - return code; -} - -static int -DumpDumpHeader(register struct iod *iodp, register Volume * vp, - afs_int32 fromtime) -{ - int code = 0; - int UseLatestReadOnlyClone = 1; - afs_int32 dumpTimes[2]; - iodp->device = vp->device; - iodp->parentId = V_parentId(vp); - iodp->dumpPartition = vp->partition; - if (!code) - code = DumpDouble(iodp, D_DUMPHEADER, DUMPBEGINMAGIC, DUMPVERSION); - if (!code) - code = - DumpInt32(iodp, 'v', - UseLatestReadOnlyClone ? V_id(vp) : V_parentId(vp)); - if (!code) - code = DumpString(iodp, 'n', 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); - return code; -} - -static int -DumpVnode(register struct iod *iodp, struct VnodeDiskObject *v, int volid, - int vnodeNumber, int dumpEverything) -{ - int code = 0; - IHandle_t *ihP; - FdHandle_t *fdP; - - if (!v || v->type == vNull) - return code; - if (!code) - code = DumpDouble(iodp, D_VNODE, vnodeNumber, v->uniquifier); - if (!dumpEverything) - return code; - if (!code) - code = DumpByte(iodp, 't', (byte) v->type); - if (!code) - code = DumpShort(iodp, 'l', v->linkCount); /* May not need this */ - if (!code) - code = DumpInt32(iodp, 'v', v->dataVersion); - if (!code) - code = DumpInt32(iodp, 'm', v->unixModifyTime); - if (!code) - code = DumpInt32(iodp, 'a', v->author); - if (!code) - code = DumpInt32(iodp, 'o', v->owner); - if (!code && v->group) - code = DumpInt32(iodp, 'g', v->group); /* default group is 0 */ - if (!code) - code = DumpShort(iodp, 'b', v->modeBits); - if (!code) - code = DumpInt32(iodp, 'p', v->parent); - if (!code) - code = DumpInt32(iodp, 's', v->serverModifyTime); - if (v->type == vDirectory) { - acl_HtonACL(VVnodeDiskACL(v)); - if (!code) - code = - DumpByteString(iodp, 'A', (byte *) VVnodeDiskACL(v), - VAclDiskSize(v)); - } - if (VNDISK_GET_INO(v)) { - IH_INIT(ihP, iodp->device, iodp->parentId, VNDISK_GET_INO(v)); - fdP = IH_OPEN(ihP); - if (fdP == NULL) { - Log("1 Volser: DumpVnode: dump: Unable to open inode %llu for vnode %u (volume %i); not dumped, error %d\n", (afs_uintmax_t) VNDISK_GET_INO(v), vnodeNumber, volid, errno); - IH_RELEASE(ihP); - return VOLSERREAD_DUMPERROR; - } - code = DumpFile(iodp, vnodeNumber, fdP); - FDH_CLOSE(fdP); - IH_RELEASE(ihP); - } - return code; -} - - -int -ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep, - int del) -{ - int i, nVnodes, offset, code, index = 0; - afs_int32 *Buf; - int cnt = 0; - int size; - StreamHandle_t *afile; - FdHandle_t *fdP; - struct VnodeClassInfo *vcp = &VnodeClassInfo[class]; - char buf[SIZEOF_LARGEDISKVNODE], zero[SIZEOF_LARGEDISKVNODE]; - register struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf; - - memset(zero, 0, sizeof(zero)); /* zero out our proto-vnode */ - fdP = IH_OPEN(vp->vnodeIndex[class].handle); - if (fdP == NULL) - return -1; - afile = FDH_FDOPEN(fdP, "r+"); - if (del) { - int cnt1 = 0; - Buf = *Bufp; - for (i = 0; i < *sizep; i++) { - if (Buf[i]) { - cnt++; - STREAM_SEEK(afile, Buf[i], 0); - code = STREAM_READ(vnode, vcp->diskSize, 1, afile); - if (code == 1) { - if (vnode->type != vNull && VNDISK_GET_INO(vnode)) { - cnt1++; - if (DoLogging) { - 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)); - DOPOLL; - } - STREAM_SEEK(afile, Buf[i], 0); - (void)STREAM_WRITE(zero, vcp->diskSize, 1, afile); /* Zero it out */ - } - Buf[i] = 0; - } - } - if (DoLogging) { - Log("RestoreVolume Cleanup: Removed %d inodes for volume %d\n", - cnt1, V_id(vp)); - } - STREAM_FLUSH(afile); /* ensure 0s are on the disk */ - OS_SYNC(afile->str_fd); - } else { - size = OS_SIZE(fdP->fd_fd); - assert(size != -1); - nVnodes = - (size <= - vcp->diskSize ? 0 : size - vcp->diskSize) >> vcp->logSize; - if (nVnodes > 0) { - Buf = (afs_int32 *) malloc(nVnodes * sizeof(afs_int32)); - if (Buf == NULL) - return 1; - memset((char *)Buf, 0, nVnodes * sizeof(afs_int32)); - STREAM_SEEK(afile, offset = vcp->diskSize, 0); - while (1) { - code = STREAM_READ(vnode, vcp->diskSize, 1, afile); - if (code != 1) { - break; - } - if (vnode->type != vNull && VNDISK_GET_INO(vnode)) { - Buf[(offset >> vcp->logSize) - 1] = offset; - cnt++; - } - offset += vcp->diskSize; - } - *Bufp = Buf; - *sizep = nVnodes; - } - } - STREAM_CLOSE(afile); - FDH_CLOSE(fdP); - return 0; -} - - -int -RestoreVolume(register struct rx_call *call, Volume * avp, int incremental, - struct restoreCookie *cookie) -{ - VolumeDiskData vol; - struct DumpHeader header; - afs_uint32 endMagic; - Error error = 0, vupdate; - register Volume *vp; - struct iod iod; - register struct iod *iodp = &iod; - afs_int32 *b1 = 0, *b2 = 0; - 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 (iod_getc(iodp) != D_VOLUMEHEADER) { - Log("1 Volser: RestoreVolume: Volume header missing from dump; not restored\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, vSmall, &b2, &s2, 0); - if (delo) { - if (b1) - free((char *)b1); - if (b2) - free((char *)b2); - b1 = b2 = 0; - } - - strncpy(vol.name, cookie->name, VOLSER_OLDMAXVOLNAME); - vol.type = cookie->type; - vol.cloneId = cookie->clone; - vol.parentId = cookie->parent; - - - tdelo = delo; - while (1) { - if (ReadVnodes(iodp, vp, 0, b1, s1, b2, s2, tdelo)) { - error = VOLSERREAD_DUMPERROR; - goto clean; - } - 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) { - Log("1 Volser: RestoreVolume: End of dump not found; restore aborted\n"); - error = VOLSERREAD_DUMPERROR; - goto clean; - } - - - if (iod_getc(iodp) != EOF) { - Log("1 Volser: RestoreVolume: Unrecognized postamble in dump; restore aborted\n"); - error = VOLSERREAD_DUMPERROR; - goto clean; - } - - if (!delo) { - ProcessIndex(vp, vLarge, &b1, &s1, 1); - ProcessIndex(vp, vSmall, &b2, &s2, 1); - } - - clean: - ClearVolumeStats(&vol); - CopyVolumeHeader(&vol, &V_disk(vp)); - V_destroyMe(vp) = 0; - VUpdateVolume(&vupdate, vp); - if (vupdate) { - Log("1 Volser: RestoreVolume: Unable to rewrite volume header; restore aborted\n"); - error = VOLSERREAD_DUMPERROR; - goto out; - } - out: - /* Free the malloced space above */ - if (b1) - free((char *)b1); - if (b2) - free((char *)b2); - return error; -} - -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) -{ - afs_int32 vnodeNumber; - char buf[SIZEOF_LARGEDISKVNODE]; - register tag; - struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf; - struct VnodeDiskObject oldvnode; - int idx; - VnodeClass class; - struct VnodeClassInfo *vcp; - IHandle_t *tmpH; - FdHandle_t *fdP; - Inode nearInode; - - tag = iod_getc(iodp); - V_pref(vp, nearInode); - while (tag == D_VNODE) { - int haveStuff = 0; - memset(buf, 0, sizeof(buf)); - if (!ReadInt32(iodp, (afs_uint32 *) & vnodeNumber)) - break; - - ReadInt32(iodp, &vnode->uniquifier); - while ((tag = iod_getc(iodp)) > D_MAX && tag != EOF) { - haveStuff = 1; - switch (tag) { - case 't': - vnode->type = (VnodeType) iod_getc(iodp); - break; - case 'l': - { - unsigned short tlc; - ReadShort(iodp, &tlc); - vnode->linkCount = (signed int)tlc; - } - break; - case 'v': - ReadInt32(iodp, &vnode->dataVersion); - break; - case 'm': - ReadInt32(iodp, &vnode->unixModifyTime); - break; - case 's': - ReadInt32(iodp, &vnode->serverModifyTime); - break; - case 'a': - ReadInt32(iodp, &vnode->author); - break; - case 'o': - ReadInt32(iodp, &vnode->owner); - break; - case 'g': - ReadInt32(iodp, (afs_uint32 *) & vnode->group); - break; - case 'b':{ - unsigned short modeBits; - ReadShort(iodp, &modeBits); - vnode->modeBits = (unsigned int)modeBits; - break; - } - case 'p': - ReadInt32(iodp, &vnode->parent); - break; - case 'A': - ReadByteString(iodp, (byte *) VVnodeDiskACL(vnode), - VAclDiskSize(vnode)); - acl_NtohACL(VVnodeDiskACL(vnode)); - break; -#ifdef AFS_LARGEFILE_ENV - case 'h': -#endif - case 'f':{ - Inode ino; - Error error; - afs_fsize_t vnodeLength; - - ino = - IH_CREATE(V_linkHandle(vp), V_device(vp), - VPartitionPath(V_partition(vp)), nearInode, - V_parentId(vp), vnodeNumber, - vnode->uniquifier, vnode->dataVersion); - if (!VALID_INO(ino)) { - perror("unable to allocate inode"); - Log("1 Volser: ReadVnodes: Restore aborted\n"); - return VOLSERREAD_DUMPERROR; - } - nearInode = ino; - VNDISK_SET_INO(vnode, ino); - IH_INIT(tmpH, vp->device, V_parentId(vp), ino); - fdP = IH_OPEN(tmpH); - if (fdP == NULL) { - IH_RELEASE(tmpH); - return VOLSERREAD_DUMPERROR; - } - vnodeLength = - volser_WriteFile(vnodeNumber, iodp, fdP, tag, &error); - VNDISK_SET_LEN(vnode, vnodeLength); - FDH_REALLYCLOSE(fdP); - IH_RELEASE(tmpH); - if (error) { - Log("1 Volser: ReadVnodes: IDEC inode %llu\n", - (afs_uintmax_t) ino); - IH_DEC(V_linkHandle(vp), ino, V_parentId(vp)); - return VOLSERREAD_DUMPERROR; - } - break; - } - } - } - - class = vnodeIdToClass(vnodeNumber); - vcp = &VnodeClassInfo[class]; - - /* Mark this vnode as in this dump - so we don't delete it later */ - if (!delo) { - idx = (vnodeIndexOffset(vcp, vnodeNumber) >> vcp->logSize) - 1; - if (class == vLarge) { - if (Lbuf && (idx < s1)) - Lbuf[idx] = 0; - } else { - if (Sbuf && (idx < s2)) - Sbuf[idx] = 0; - } - } - - 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"); - 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"); - FDH_REALLYCLOSE(fdP); - return VOLSERREAD_DUMPERROR; - } - if (FDH_READ(fdP, &oldvnode, sizeof(oldvnode)) == - sizeof(oldvnode)) { - if (oldvnode.type != vNull && VNDISK_GET_INO(&oldvnode)) { - IH_DEC(V_linkHandle(vp), VNDISK_GET_INO(&oldvnode), - V_parentId(vp)); - } - } - 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"); - 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"); - FDH_REALLYCLOSE(fdP); - return VOLSERREAD_DUMPERROR; - } - FDH_CLOSE(fdP); - } - } - iod_ungetc(iodp, tag); - - - return 0; -} - - -/* called with disk file only. Note that we don't have to worry about rx_Read - * needing to read an ungetc'd character, since the ReadInt32 will have read - * it instead. - */ -static afs_fsize_t -volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP, int tag, - Error * status) -{ - afs_int32 code; - afs_fsize_t filesize; - afs_fsize_t written = 0; - register afs_uint32 size = 8192; - register afs_fsize_t nbytes; - unsigned char *p; - - - *status = 0; -#ifdef AFS_64BIT_ENV - { - afs_uint32 filesize_high = 0L, filesize_low = 0L; -#ifdef AFS_LARGEFILE_ENV - if (tag == 'h') { - if (!ReadInt32(iodp, &filesize_high)) { - *status = 1; - return 0; - } - } -#endif /* !AFS_LARGEFILE_ENV */ - 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; - return (0); - } - for (nbytes = filesize; nbytes; nbytes -= size) { - 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); - *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"); - *status = 4; - break; - } - } - free(p); - return (written); -} - -static int -ReadDumpHeader(register struct iod *iodp, struct DumpHeader *hp) -{ - register tag; - afs_uint32 beginMagic; - if (iod_getc(iodp) != D_DUMPHEADER || !ReadInt32(iodp, &beginMagic) - || !ReadInt32(iodp, (afs_uint32 *) & hp->version) - || beginMagic != DUMPBEGINMAGIC) - return 0; - hp->volumeId = 0; - hp->nDumpTimes = 0; - while ((tag = iod_getc(iodp)) > D_MAX) { - unsigned short arrayLength; - register int i; - switch (tag) { - case 'v': - if (!ReadInt32(iodp, &hp->volumeId)) - return 0; - break; - case 'n': - ReadString(iodp, hp->volumeName, sizeof(hp->volumeName)); - break; - case 't': - if (!ReadShort(iodp, &arrayLength)) - return 0; - hp->nDumpTimes = (arrayLength >> 1); - for (i = 0; i < hp->nDumpTimes; i++) - if (!ReadInt32(iodp, (afs_uint32 *) & hp->dumpTimes[i].from) - || !ReadInt32(iodp, (afs_uint32 *) & hp->dumpTimes[i].to)) - return 0; - break; - } - } - if (!hp->volumeId || !hp->nDumpTimes) { - return 0; - } - 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 */ - afs_uint64 addvar; - -/* if (!code) code = DumpTag(iodp, D_VOLUMEHEADER); */ - FillInt64(addvar,0, 1); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) {code = DumpInt32(iodp, 'i',V_id(vp));} */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'v',V_stamp(vp).version); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpString(iodp, 'n',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)); */ - FillInt64(addvar,0, 2); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpBool(iodp, 'b',V_blessed(vp)); */ - FillInt64(addvar,0, 2); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'u',V_uniquifier(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpByte(iodp, 't',(byte)V_type(vp)); */ - FillInt64(addvar,0, 2); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code){ code = DumpInt32(iodp, 'p',V_parentId(vp));} */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'c',V_cloneId(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'q',V_maxquota(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'm',V_minquota(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'd',V_diskused(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'f',V_filecount(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'a', V_accountNumber(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'o', V_owner(vp)); */ - 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 *\/ */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'A',V_accessDate(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'U',V_updateDate(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'E',V_expirationDate(vp)); */ - 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 *\/ */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpString(iodp, 'O',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 */ -/* * 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); */ - 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])); */ - 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)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'Z', V_dayUse(vp)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); - return code; -} - -static int -SizeDumpEnd(register struct iod *iodp, register struct volintSize *v_size) -{ - int code = 0; - afs_uint64 addvar; - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); - return code; -} - -int -SizeDumpVolume(register struct rx_call *call, register Volume * vp, - afs_int32 fromtime, int dumpAllDirs, - register struct volintSize *v_size) -{ - 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]; */ - afs_uint64 addvar; -/* iodp->device = vp->device; */ -/* iodp->parentId = V_parentId(vp); */ -/* iodp->dumpPartition = vp->partition; */ - - ZeroInt64(v_size->dump_size); /* initialize the size */ -/* if (!code) code = DumpDouble(iodp, D_DUMPHEADER, DUMPBEGINMAGIC, DUMPVERSION); */ - 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)); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpString(iodp, 'n',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); */ - FillInt64(addvar,0, (3 + 4 * 2)); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); - 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; - afs_uint64 addvar; - - if (!v || v->type == vNull) - return code; -/* if (!code) code = DumpDouble(iodp, D_VNODE, vnodeNumber, v->uniquifier); */ - 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); */ - 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 *\/ */ - FillInt64(addvar,0, 3); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'v', v->dataVersion); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'm', v->unixModifyTime); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'a', v->author); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'o', v->owner); */ - 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) { - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); - } -/* if (!code) code = DumpShort(iodp, 'b', v->modeBits); */ - FillInt64(addvar,0, 3); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 'p', v->parent); */ - FillInt64(addvar,0, 5); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); -/* if (!code) code = DumpInt32(iodp, 's', v->serverModifyTime); */ - 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)); */ - FillInt64(addvar,0, (1 + VAclDiskSize(v))); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); - } - - if (VNDISK_GET_INO(v)) { - FillInt64(addvar,0, (v->length + 5)); - AddUInt64(v_size->dump_size, addvar, &v_size->dump_size); - } - 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; -} diff --git a/src/volser/lockdata.h b/src/volser/lockdata.h deleted file mode 100644 index 7c8df8b8c..000000000 --- a/src/volser/lockdata.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 - */ - -#ifndef _LOCKDATA_ -#define _LOCKDATA_ 1 - -#define ZERO 2147617029 /*to be replaced by 0L */ -#define N_SECURITY_OBJECTS 1 - - -struct aqueue { - char name[VOLSER_MAXVOLNAME]; /* related to max volname allowed in the vldb */ - afs_int32 ids[3]; - afs_int32 copyDate[3]; - int isValid[3]; - struct aqueue *next; -}; - -struct qHead { - int count; - struct aqueue *next; -}; - -#endif /* _LOCKDATA_ */ diff --git a/src/volser/lockprocs.c b/src/volser/lockprocs.c deleted file mode 100644 index 9d175bd25..000000000 --- a/src/volser/lockprocs.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * 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 - */ - -/* - * Module: lockprocs.c - * System: Volser - * Instituition: ITC, CMU - * Date: December, 88 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/lockprocs.c,v 1.8 2003/07/15 23:17:48 shadow Exp $"); - -#include -#ifdef AFS_NT40_ENV -#include -#else -#include -#endif -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif -#include -#include -#include -#include -#include -#include -#include "volint.h" -#include "volser.h" -#include "lockdata.h" - -/* Finds an index in VLDB entry that matches the volume type, server, and partition. - * If type is zero, will match first index of ANY type (RW, BK, or RO). - * If server is zero, will match first index of ANY server and partition - * Zero is a valid partition field. - */ -int -FindIndex(entry, server, part, type) - struct nvldbentry *entry; - afs_int32 server, part, type; -{ - int e; - afs_int32 error = 0; - - for (e = 0; (e < entry->nServers) && !error; e++) { - if (!type || (entry->serverFlags[e] & type)) { - if ((!server || (entry->serverPartition[e] == part)) - && (!server - || VLDB_IsSameAddrs(entry->serverNumber[e], server, - &error))) - break; - if (type == ITSRWVOL) - return -1; /* quit when we are looking for RW entry (there's only 1) */ - } - } - - if (error) { - fprintf(STDERR, - "Failed to get info about server's %d address(es) from vlserver (err=%d)\n", - entry->serverNumber[e], error); - return -1; - } - - if (e >= entry->nServers) - return -1; /* Didn't find it */ - - return e; /* return the index */ -} - -/* Changes the rw site only */ -void -SetAValue(entry, oserver, opart, nserver, npart, type) - struct nvldbentry *entry; - afs_int32 oserver, opart, nserver, npart, type; -{ - int e; - afs_int32 error = 0; - - e = FindIndex(entry, oserver, opart, type); - if (e == -1) - return; /* If didn't find it, just return */ - - entry->serverNumber[e] = nserver; - entry->serverPartition[e] = npart; - - /* Now move rest of entries up */ - if ((nserver == 0L) && (npart == 0L)) { - for (e++; e < entry->nServers; e++) { - entry->serverNumber[e - 1] = entry->serverNumber[e]; - entry->serverPartition[e - 1] = entry->serverPartition[e]; - entry->serverFlags[e - 1] = entry->serverFlags[e]; - } - } -} - -/* Changes the RW site only */ -Lp_SetRWValue(entry, oserver, opart, nserver, npart) - struct nvldbentry *entry; - afs_int32 oserver, opart, nserver, npart; -{ - SetAValue(entry, oserver, opart, nserver, npart, ITSRWVOL); -} - -/* Changes the RO site only */ -Lp_SetROValue(entry, oserver, opart, nserver, npart) - struct nvldbentry *entry; - afs_int32 oserver, opart, nserver, npart; -{ - SetAValue(entry, oserver, opart, nserver, npart, ITSROVOL); -} - -/* Returns success if this server and partition matches the RW entry */ -Lp_Match(server, part, entry) - afs_int32 server, part; - struct nvldbentry *entry; -{ - if (FindIndex(entry, server, part, ITSRWVOL) == -1) - return 0; - return 1; -} - -/* Return the index of the RO entry (plus 1) if it exists, else return 0 */ -Lp_ROMatch(server, part, entry) - afs_int32 server, part; - struct nvldbentry *entry; -{ - return (FindIndex(entry, server, part, ITSROVOL) + 1); -} - -/* Return the index of the RW entry if it exists, else return -1 */ -Lp_GetRwIndex(entry) - struct nvldbentry *entry; -{ - return (FindIndex(entry, 0, 0, ITSRWVOL)); -} - -/*initialize queue pointed by */ -Lp_QInit(ahead) - struct qHead *ahead; -{ - ahead->count = 0; - ahead->next = NULL; -} - -/*add in front of queue */ -Lp_QAdd(ahead, elem) - struct qHead *ahead; - struct aqueue *elem; -{ - struct aqueue *temp; - - if (ahead->count == 0) { - ahead->count += 1; - ahead->next = elem; - elem->next = NULL; - } else { - temp = ahead->next; - ahead->count += 1; - ahead->next = elem; - elem->next = temp; - } -} - -Lp_QScan(ahead, id, success, elem) - struct qHead *ahead; - struct aqueue **elem; - afs_int32 id; - int *success; -{ - struct aqueue *cptr; - - cptr = ahead->next; - while (cptr != NULL) { - if (cptr->ids[RWVOL] == id) { - *success = 1; - *elem = cptr; - return 0; - } - cptr = cptr->next; - } - *success = 0; - return 0; -} - -/*return the element in the beginning of the queue , free -*the space used by that element . indicates if enumeration was ok*/ -Lp_QEnumerate(ahead, success, elem) - struct qHead *ahead; - struct aqueue *elem; - int *success; -{ - int i; - struct aqueue *temp; - - if (ahead->count > 0) { /*more elements left */ - ahead->count -= 1; - temp = ahead->next; - ahead->next = ahead->next->next; - strncpy(elem->name, temp->name, VOLSER_OLDMAXVOLNAME); - for (i = 0; i < 3; i++) { - elem->ids[i] = temp->ids[i]; - elem->copyDate[i] = temp->copyDate[i]; - elem->isValid[i] = temp->isValid[i]; - } - elem->next = NULL; - *success = 1; - free(temp); - } else /*queue is empty */ - *success = 0; -} - -Lp_QTraverse(ahead) - struct qHead *ahead; -{ - int count; - struct aqueue *old, *new; - - old = ahead->next; - new = old->next; - count = ahead->count; - printf - ("traversing the internal queue, which groups all the related volumes on a per partition basis\n"); - while (count > 0) { - printf("---------------------------\n"); - printf("%s RW-Id %lu", old->name, (unsigned long)old->ids[RWVOL]); - if (old->isValid[RWVOL]) - printf(" valid "); - else - printf(" invalid "); - printf("RO-Id %lu", (unsigned long)old->ids[ROVOL]); - if (old->isValid[ROVOL]) - printf(" valid "); - else - printf(" invalid "); - printf("BACKUP-Id %lu", (unsigned long)old->ids[BACKVOL]); - if (old->isValid[BACKVOL]) - printf(" valid "); - else - printf(" invalid "); - printf("\n"); - printf("---------------------------\n"); - old = new; - if (count != 1) - new = new->next; - count--; - } -} diff --git a/src/volser/physio.c b/src/volser/physio.c deleted file mode 100644 index f8f5a91f7..000000000 --- a/src/volser/physio.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/physio.c,v 1.11 2003/12/09 23:07:57 shadow Exp $"); - -#include -#ifdef AFS_NT40_ENV -#include -#else -#include -#include -#include -#endif -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif -#ifdef AFS_SUN5_ENV -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vol.h" - -/* returns 0 on success, errno on failure */ -int -ReallyRead(DirHandle * file, int block, char *data) -{ - FdHandle_t *fdP; - int code; - errno = 0; - fdP = IH_OPEN(file->dirh_handle); - if (fdP == NULL) { - code = errno; - return code; - } - if (FDH_SEEK(fdP, block * AFS_PAGESIZE, SEEK_SET) < 0) { - code = errno; - FDH_REALLYCLOSE(fdP); - return code; - } - code = FDH_READ(fdP, data, AFS_PAGESIZE); - if (code != AFS_PAGESIZE) { - if (code < 0) - code = errno; - else - code = EIO; - FDH_REALLYCLOSE(fdP); - return code; - } - FDH_CLOSE(fdP); - return 0; -} - -/* returns 0 on success, errno on failure */ -int -ReallyWrite(DirHandle * file, int block, char *data) -{ - FdHandle_t *fdP; - extern int VolumeChanged; - int code; - - errno = 0; - - fdP = IH_OPEN(file->dirh_handle); - if (fdP == NULL) { - code = errno; - return code; - } - if (FDH_SEEK(fdP, block * AFS_PAGESIZE, SEEK_SET) < 0) { - code = errno; - FDH_REALLYCLOSE(fdP); - return code; - } - code = FDH_WRITE(fdP, data, AFS_PAGESIZE); - if (code != AFS_PAGESIZE) { - if (code < 0) - code = errno; - else - code = EIO; - FDH_REALLYCLOSE(fdP); - return code; - } - FDH_CLOSE(fdP); - VolumeChanged = 1; - return 0; -} - -/* SetSalvageDirHandle: - * Create a handle to a directory entry and reference it (IH_INIT). - * The handle needs to be dereferenced with the FidZap() routine. - */ -void -SetSalvageDirHandle(DirHandle * dir, afs_int32 volume, afs_int32 device, - Inode inode) -{ - private SalvageCacheCheck = 1; - memset(dir, 0, sizeof(DirHandle)); - - dir->dirh_volume = volume; - dir->dirh_device = device; - dir->dirh_inode = inode; - IH_INIT(dir->dirh_handle, device, volume, inode); - - /* Always re-read for a new dirhandle */ - dir->dirh_cacheCheck = SalvageCacheCheck++; -} - -void -FidZap(DirHandle * file) -{ - IH_RELEASE(file->dirh_handle); - memset(file, 0, sizeof(DirHandle)); -} - -void -FidZero(DirHandle * file) -{ - memset(file, 0, sizeof(DirHandle)); -} - -int -FidEq(DirHandle * afile, DirHandle * bfile) -{ - if (afile->dirh_volume != bfile->dirh_volume) - return 0; - if (afile->dirh_device != bfile->dirh_device) - return 0; - if (afile->dirh_cacheCheck != bfile->dirh_cacheCheck) - return 0; - if (afile->dirh_inode != bfile->dirh_inode) - return 0; - return 1; -} - -int -FidVolEq(DirHandle * afile, afs_int32 vid) -{ - if (afile->dirh_volume != vid) - return 0; - return 1; -} - -void -FidCpy(DirHandle * tofile, DirHandle * fromfile) -{ - *tofile = *fromfile; - IH_COPY(tofile->dirh_handle, fromfile->dirh_handle); -} - -void -Die(char *msg) -{ - printf("%s\n", msg); - assert(1 == 2); -} diff --git a/src/volser/restorevol.c b/src/volser/restorevol.c deleted file mode 100644 index 8e4782245..000000000 --- a/src/volser/restorevol.c +++ /dev/null @@ -1,993 +0,0 @@ -/* - * 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 - */ - -/* - * Read a vos dump and recreate the tree. - * - * restorevol [-file ] - * [-dir ] - * [-extension ] - * [-mountpoint ] - * [-umask ] - * - * 1. The dump file will be restored within the current or that specified with -dir. - * 2. Within this dir, a subdir is created. It's name is the RW volume name - * that was dumped. An extension can be appended to this directory name - * with -extension. - * 3. All mountpoints will appear as symbolic links to the volume. The - * pathname to the volume will be either that in -mountpoint, or -dir. - * Symbolic links remain untouched. - * 4. You can change your umask during the restore with -umask. Otherwise, it - * uses your current umask. Mode bits for directories are 0777 (then - * AND'ed with the umask). Mode bits for files are the owner mode bits - * duplicated accross group and user (then AND'ed with the umask). - * 5. For restores of full dumps, if a directory says it has a file and - * the file is not found, then a symbolic link "AFSFile-<#>" will - * appear in that restored tree. Restores of incremental dumps remove - * all these files at the end (expensive because it is a tree search). - * 6. If a file or directory was found in the dump but found not to be - * connected to the hierarchical tree, then the file or directory - * will be connected at the root of the tree as "__ORPHANEDIR__.<#>" - * or "__ORPHANFILE__.<#>". - * 7. ACLs are not restored. - * - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/restorevol.c,v 1.13 2003/12/05 08:36:06 shadow Exp $"); - -#include -#include -#include -#include -#include -#include -#include "volint.h" -#include "dump.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif - - -char rootdir[MAXPATHLEN]; -char mntroot[MAXPATHLEN]; -#define ADIR "AFSDir-" -#define AFILE "AFSFile-" -#define ODIR "__ORPHANEDIR__." -#define OFILE "__ORPHANFILE__." - -int inc_dump = 0; -FILE *dumpfile; - -afs_int32 -readvalue(size) -{ - afs_int32 value, s; - int code; - char *ptr; - - value = 0; - ptr = (char *)&value; - - s = sizeof(value) - size; - if (size < 0) { - fprintf(stderr, "Too much data in afs_int32\n"); - return 0; - } - - code = fread(&ptr[s], 1, size, dumpfile); - if (code != size) - fprintf(stderr, "Code = %d; Errno = %d\n", code, errno); - - return (value); -} - -char -readchar() -{ - char value; - int code; - char *ptr; - - value = '\0'; - code = fread(&value, 1, 1, dumpfile); - if (code != 1) - fprintf(stderr, "Code = %d; Errno = %d\n", code, errno); - - return (value); -} - -#define BUFSIZE 16384 -char buf[BUFSIZE]; - -char -readdata(buffer, size) - char *buffer; - afs_sfsize_t size; -{ - int code; - afs_int32 s; - - if (!buffer) { - while (size > 0) { - s = (afs_int32) ((size > BUFSIZE) ? BUFSIZE : size); - code = fread(buf, 1, s, dumpfile); - if (code != s) - fprintf(stderr, "Code = %d; Errno = %d\n", code, errno); - size -= s; - } - } else { - code = fread(buffer, 1, size, dumpfile); - if (code != size) { - if (code < 0) - fprintf(stderr, "Code = %d; Errno = %d\n", code, errno); - else - fprintf(stderr, "Read %d bytes out of %lld\n", code, (afs_uintmax_t)size); - } - if ((code >= 0) && (code < BUFSIZE)) - buffer[size] = 0; /* Add null char at end */ - } -} - -afs_int32 -ReadDumpHeader(dh) - struct DumpHeader *dh; /* Defined in dump.h */ -{ - int code, i, done; - char tag, c; - afs_int32 magic; - -/* memset(&dh, 0, sizeof(dh)); */ - - magic = ntohl(readvalue(4)); - dh->version = ntohl(readvalue(4)); - - done = 0; - while (!done) { - tag = readchar(); - switch (tag) { - case 'v': - dh->volumeId = ntohl(readvalue(4)); - break; - - case 'n': - for (i = 0, c = 'a'; c != '\0'; i++) { - dh->volumeName[i] = c = readchar(); - } - dh->volumeName[i] = c; - break; - - case 't': - dh->nDumpTimes = ntohl(readvalue(2)) >> 1; - for (i = 0; i < dh->nDumpTimes; i++) { - dh->dumpTimes[i].from = ntohl(readvalue(4)); - dh->dumpTimes[i].to = ntohl(readvalue(4)); - } - break; - - default: - done = 1; - break; - } - } - - return ((afs_int32) tag); -} - -struct volumeHeader { - afs_int32 volumeId; - char volumeName[100]; - afs_int32 volType; - afs_int32 uniquifier; - afs_int32 parentVol; - afs_int32 cloneId; - afs_int32 maxQuota; - afs_int32 minQuota; - afs_int32 diskUsed; - afs_int32 fileCount; - afs_int32 accountNumber; - afs_int32 owner; - afs_int32 creationDate; - afs_int32 accessDate; - afs_int32 updateDate; - afs_int32 expirationDate; - afs_int32 backupDate; - afs_int32 dayUseDate; - afs_int32 dayUse; - afs_int32 weekCount; - afs_int32 weekUse[100]; /* weekCount of these */ - char motd[1024]; - int inService; - int blessed; - char message[1024]; -}; - -afs_int32 -ReadVolumeHeader(count) - afs_int32 count; -{ - struct volumeHeader vh; - int code, i, done, entries; - char tag, c; - -/* memset(&vh, 0, sizeof(vh)); */ - - done = 0; - while (!done) { - tag = readchar(); - switch (tag) { - case 'i': - vh.volumeId = ntohl(readvalue(4)); - break; - - case 'v': - ntohl(readvalue(4)); /* version stamp - ignore */ - break; - - case 'n': - for (i = 0, c = 'a'; c != '\0'; i++) { - vh.volumeName[i] = c = readchar(); - } - vh.volumeName[i] = c; - break; - - case 's': - vh.inService = ntohl(readvalue(1)); - break; - - case 'b': - vh.blessed = ntohl(readvalue(1)); - break; - - case 'u': - vh.uniquifier = ntohl(readvalue(4)); - break; - - case 't': - vh.volType = ntohl(readvalue(1)); - break; - - case 'p': - vh.parentVol = ntohl(readvalue(4)); - break; - - case 'c': - vh.cloneId = ntohl(readvalue(4)); - break; - - case 'q': - vh.maxQuota = ntohl(readvalue(4)); - break; - - case 'm': - vh.minQuota = ntohl(readvalue(4)); - break; - - case 'd': - vh.diskUsed = ntohl(readvalue(4)); - break; - - case 'f': - vh.fileCount = ntohl(readvalue(4)); - break; - - case 'a': - vh.accountNumber = ntohl(readvalue(4)); - break; - - case 'o': - vh.owner = ntohl(readvalue(4)); - break; - - case 'C': - vh.creationDate = ntohl(readvalue(4)); - break; - - case 'A': - vh.accessDate = ntohl(readvalue(4)); - break; - - case 'U': - vh.updateDate = ntohl(readvalue(4)); - break; - - case 'E': - vh.expirationDate = ntohl(readvalue(4)); - break; - - case 'B': - vh.backupDate = ntohl(readvalue(4)); - break; - - case 'O': - for (i = 0, c = 'a'; c != '\0'; i++) { - vh.message[i] = c = readchar(); - } - vh.volumeName[i] = c; - break; - - case 'W': - vh.weekCount = ntohl(readvalue(2)); - for (i = 0; i < vh.weekCount; i++) { - vh.weekUse[i] = ntohl(readvalue(4)); - } - break; - - case 'M': - for (i = 0, c = 'a'; c != '\0'; i++) { - vh.motd[i] = c = readchar(); - } - break; - - case 'D': - vh.dayUseDate = ntohl(readvalue(4)); - break; - - case 'Z': - vh.dayUse = ntohl(readvalue(4)); - break; - - default: - done = 1; - break; - } - } - - return ((afs_int32) tag); -} - -struct vNode { - afs_int32 vnode; - afs_int32 uniquifier; - afs_int32 type; - afs_int32 linkCount; - afs_int32 dataVersion; - afs_int32 unixModTime; - afs_int32 servModTime; - afs_int32 author; - afs_int32 owner; - afs_int32 group; - afs_int32 modebits; - afs_int32 parent; - char acl[192]; -#ifdef notdef - struct acl_accessList { - int size; /*size of this access list in bytes, including MySize itself */ - int version; /*to deal with upward compatibility ; <= ACL_ACLVERSION */ - int total; - int positive; /* number of positive entries */ - int negative; /* number of minus entries */ - struct acl_accessEntry { - int id; /*internally-used ID of user or group */ - int rights; /*mask */ - } entries[100]; - } acl; -#endif - afs_sfsize_t dataSize; -}; - -#define MAXNAMELEN 256 - -afs_int32 -ReadVNode(count) - afs_int32 count; -{ - struct vNode vn; - int code, i, done, entries; - char tag, c; - char dirname[MAXNAMELEN], linkname[MAXNAMELEN], lname[MAXNAMELEN]; - char parentdir[MAXNAMELEN], vflink[MAXNAMELEN]; - char filename[MAXNAMELEN], fname[MAXNAMELEN]; - int len; - afs_int32 vnode; - afs_int32 mode = 0; - -/* memset(&vn, 0, sizeof(vn)); */ - vn.dataSize = 0; - vn.vnode = 0; - vn.parent = 0; - vn.type = 0; - - vn.vnode = ntohl(readvalue(4)); - vn.uniquifier = ntohl(readvalue(4)); - - done = 0; - while (!done) { - tag = readchar(); - switch (tag) { - case 't': - vn.type = ntohl(readvalue(1)); - break; - - case 'l': - vn.linkCount = ntohl(readvalue(2)); - break; - - case 'v': - vn.dataVersion = ntohl(readvalue(4)); - break; - - case 'm': - vn.unixModTime = ntohl(readvalue(4)); - break; - - case 's': - vn.servModTime = ntohl(readvalue(4)); - break; - - case 'a': - vn.author = ntohl(readvalue(4)); - break; - - case 'o': - vn.owner = ntohl(readvalue(4)); - break; - - case 'g': - vn.group = ntohl(readvalue(4)); - break; - - case 'b': - vn.modebits = ntohl(readvalue(2)); - break; - - case 'p': - vn.parent = ntohl(readvalue(4)); - break; - - case 'A': - readdata(vn.acl, 192); /* Skip ACL data */ - break; - -#ifdef AFS_LARGEFILE_ENV - case 'h': - { - afs_uint32 hi, lo; - hi = ntohl(readvalue(4)); - lo = ntohl(readvalue(4)); - FillInt64(vn.dataSize, hi, lo); - } - goto common_vnode; -#endif /* !AFS_LARGEFILE_ENV */ - - case 'f': - vn.dataSize = ntohl(readvalue(4)); - - common_vnode: - /* parentdir is the name of this dir's vnode-file-link - * or this file's parent vnode-file-link. - * "./AFSDir-<#>". It's a symbolic link to its real dir. - * The parent dir and symbolic link to it must exist. - */ - vnode = ((vn.type == 2) ? vn.vnode : vn.parent); - if (vnode == 1) - strncpy(parentdir, rootdir, sizeof parentdir); - else { - afs_snprintf(parentdir, sizeof parentdir, "%s/%s%d", rootdir, - ADIR, vnode); - - len = readlink(parentdir, linkname, MAXNAMELEN); - if (len < 0) { - /* parentdir does not exist. So create an orphan dir. - * and then link the parentdir to the orphaned dir. - */ - afs_snprintf(linkname, sizeof linkname, "%s/%s%d", - rootdir, ODIR, vnode); - code = mkdir(linkname, 0777); - if ((code < 0) && (errno != EEXIST)) { - fprintf(stderr, - "Error creating directory %s code=%d;%d\n", - linkname, code, errno); - } - - /* Link the parentdir to it - now parentdir exists */ - afs_snprintf(linkname, sizeof linkname, "%s%d/", ODIR, - vnode); - code = symlink(linkname, parentdir); - if (code) { - fprintf(stderr, - "Error creating symlink %s -> %s code=%d;%d\n", - parentdir, linkname, code, errno); - } - } - } - - if (vn.type == 2) { - /*ITSADIR*/ - /* We read the directory entries. If the entry is a - * directory, the subdir is created and the root dir - * will contain a link to it. If its a file, we only - * create a symlink in the dir to the file name. - */ - char *buffer; - unsigned short j; - afs_int32 this_vn; - char *this_name; - - struct DirEntry { - char flag; - char length; - unsigned short next; - struct MKFid { - afs_int32 vnode; - afs_int32 vunique; - } fid; - char name[20]; - }; - - struct Pageheader { - unsigned short pgcount; - unsigned short tag; - char freecount; - char freebitmap[8]; - char padding[19]; - }; - - struct DirHeader { - struct Pageheader header; - char alloMap[128]; - unsigned short hashTable[128]; - }; - - struct Page0 { - struct DirHeader header; - struct DirEntry entry[1]; - } *page0; - - - buffer = NULL; - buffer = (char *)malloc(vn.dataSize); - - readdata(buffer, vn.dataSize); - page0 = (struct Page0 *)buffer; - - /* Step through each bucket in the hash table, i, - * and follow each element in the hash chain, j. - * This gives us each entry of the dir. - */ - for (i = 0; i < 128; i++) { - for (j = ntohs(page0->header.hashTable[i]); j; - j = ntohs(page0->entry[j].next)) { - j -= 13; - this_vn = ntohl(page0->entry[j].fid.vnode); - this_name = page0->entry[j].name; - - if ((strcmp(this_name, ".") == 0) - || (strcmp(this_name, "..") == 0)) - continue; /* Skip these */ - - /* For a directory entry, create it. Then create the - * link (from the rootdir) to this directory. - */ - if (this_vn & 1) { - /*ADIRENTRY*/ - /* dirname is the directory to create. - * vflink is what will link to it. - */ - afs_snprintf(dirname, sizeof dirname, "%s/%s", - parentdir, this_name); - afs_snprintf(vflink, sizeof vflink, "%s/%s%d", - rootdir, ADIR, this_vn); - - /* The link and directory may already exist */ - len = readlink(vflink, linkname, MAXNAMELEN); - if (len < 0) { - /* Doesn't already exist - so create the directory. - * umask will pare the mode bits down. - */ - code = mkdir(dirname, 0777); - if ((code < 0) && (errno != EEXIST)) { - fprintf(stderr, - "Error creating directory %s code=%d;%d\n", - dirname, code, errno); - } - } else { - /* Does already exist - so move the directory. - * It was created originally as orphaned. - */ - linkname[len - 1] = '\0'; /* remove '/' at end */ - afs_snprintf(lname, sizeof lname, "%s/%s", - rootdir, linkname); - code = rename(lname, dirname); - if (code) { - fprintf(stderr, - "Error renaming %s to %s code=%d;%d\n", - lname, dirname, code, errno); - } - } - - /* Now create/update the link to the new/moved directory */ - if (vn.vnode == 1) - afs_snprintf(dirname, sizeof dirname, "%s/", - this_name); - else - afs_snprintf(dirname, sizeof dirname, - "%s%d/%s/", ADIR, vn.vnode, - this_name); - unlink(vflink); - code = symlink(dirname, vflink); - if (code) { - fprintf(stderr, - "Error creating symlink %s -> %s code=%d;%d\n", - vflink, dirname, code, errno); - } - } - /*ADIRENTRY*/ - /* For a file entry, we remember the name of the file - * by creating a link within the directory. Restoring - * the file will later remove the link. - */ - else { - /*AFILEENTRY*/ afs_snprintf(vflink, - sizeof vflink, - "%s/%s%d", parentdir, - AFILE, this_vn); - - code = symlink(this_name, vflink); - if ((code < 0) && (errno != EEXIST)) { - fprintf(stderr, - "Error creating symlink %s -> %s code=%d;%d\n", - vflink, page0->entry[j].name, code, - errno); - } - } - /*AFILEENTRY*/} - } - free(buffer); - } - /*ITSADIR*/ - else if (vn.type == 1) { - /*ITSAFILE*/ - /* A file vnode. So create it into the desired directory. A - * link should exist in the directory naming the file. - */ - int fid; - int lfile; - afs_sfsize_t size, s; - - /* Check if its vnode-file-link exists. If not, - * then the file will be an orphaned file. - */ - lfile = 1; - afs_snprintf(filename, sizeof filename, "%s/%s%d", parentdir, - AFILE, vn.vnode); - len = readlink(filename, fname, MAXNAMELEN); - if (len < 0) { - afs_snprintf(filename, sizeof filename, "%s/%s%d", - rootdir, OFILE, vn.vnode); - lfile = 0; /* no longer a linked file; a direct path */ - } - - /* Create a mode for the file. Use the owner bits and - * duplicate them across group and other. The umask - * will remove what we don't want. - */ - mode = (vn.modebits >> 6) & 0x7; - mode |= (mode << 6) | (mode << 3); - - /* Write the file out */ - fid = open(filename, (O_CREAT | O_WRONLY | O_TRUNC), mode); - size = vn.dataSize; - while (size > 0) { - s = (afs_int32) ((size > BUFSIZE) ? BUFSIZE : size); - code = fread(buf, 1, s, dumpfile); - if (code > 0) { - (void)write(fid, buf, code); - size -= code; - } - if (code != s) { - if (code < 0) - fprintf(stderr, "Code = %d; Errno = %d\n", code, - errno); - else { - char tmp[100]; - (void)afs_snprintf(tmp, sizeof tmp, - "Read %llu bytes out of %llu", - (afs_uintmax_t) (vn.dataSize - - size), - (afs_uintmax_t) vn.dataSize); - fprintf(stderr, "%s\n", tmp); - } - break; - } - } - close(fid); - if (size != 0) { - fprintf(stderr, " File %s (%s) is incomplete\n", - filename, fname); - } - - /* Remove the link to the file */ - if (lfile) { - unlink(filename); - } - } - /*ITSAFILE*/ - else if (vn.type == 3) { - /*ITSASYMLINK*/ - /* A symlink vnode. So read it into the desired directory. This could - * also be a mount point. If the volume is being restored to AFS, this - * will become a mountpoint. If not, it becomes a symlink to no-where. - */ - int fid; - afs_int32 size, s; - - /* Check if its vnode-file-link exists and create pathname - * of the symbolic link. If it doesn't exist, - * then the link will be an orphaned link. - */ - afs_snprintf(linkname, sizeof linkname, "%s/%s%d", parentdir, - AFILE, vn.vnode); - len = readlink(linkname, fname, MAXNAMELEN); - if (len < 0) { - afs_snprintf(filename, sizeof filename, "%s/%s%d", - rootdir, OFILE, vn.vnode); - } else { - fname[len] = '\0'; - afs_snprintf(filename, sizeof filename, "%s/%s", - parentdir, fname); - } - - /* Read the link in, delete it, and then create it */ - readdata(buf, vn.dataSize); - - /* If a mountpoint, change its link path to mountroot */ - s = strlen(buf); - if (((buf[0] == '%') || (buf[0] == '#')) - && (buf[s - 1] == '.')) { - /* This is a symbolic link */ - buf[s - 1] = 0; /* Remove prefix '.' */ - strcpy(lname, &buf[1]); /* Remove postfix '#' or '%' */ - strcpy(buf, mntroot); - strcat(buf, lname); - } - - unlink(filename); - code = symlink(buf, filename); - if (code) { - fprintf(stderr, - "Error creating symlink %s -> %s code=%d;%d\n", - filename, buf, code, errno); - } - - /* Remove the symbolic link */ - unlink(linkname); - } - /*ITSASYMLINK*/ - else { - fprintf(stderr, "Unknown Vnode block\n"); - } - break; - - default: - done = 1; - break; - } - } - if (vn.type == 0) - inc_dump = 1; - - return ((afs_int32) tag); -} - -WorkerBee(as, arock) - struct cmd_syndesc *as; - char *arock; -{ - int code = 0, c, len; - afs_int32 type, count, vcount; - DIR *dirP, *dirQ; - struct dirent *dirE, *dirF; - char fname[MAXNAMELEN], name[MAXNAMELEN], lname[MAXNAMELEN], - mname[MAXNAMELEN]; - char thisdir[MAXPATHLEN], *t; - struct DumpHeader dh; /* Defined in dump.h */ -#if 0/*ndef HAVE_GETCWD*/ /* XXX enable when autoconf happens */ - extern char *getwd(); -#define getcwd(x,y) getwd(x) -#endif - - if (as->parms[0].items) { /* -file */ - dumpfile = fopen(as->parms[0].items->data, "r"); - if (!dumpfile) { - fprintf(stderr, "Cannot open '%s'. Code = %d\n", - as->parms[0].items->data, errno); - goto cleanup; - } - } else { - dumpfile = (FILE *) stdin; /* use stdin */ - } - - /* Read the dump header. From it we get the volume name */ - type = ntohl(readvalue(1)); - if (type != 1) { - fprintf(stderr, "Expected DumpHeader\n"); - code = -1; - goto cleanup; - } - type = ReadDumpHeader(&dh); - - /* Get the root directory we restore to */ - if (as->parms[1].items) { /* -dir */ - strcpy(rootdir, as->parms[1].items->data); - } else { - strcpy(rootdir, "."); - } - strcat(rootdir, "/"); - - /* Append the RW volume name to the root directory */ - strcat(rootdir, dh.volumeName); - len = strlen(rootdir); - if (strcmp(".backup", rootdir + len - 7) == 0) { - rootdir[len - 7] = 0; - } else if (strcmp(".readonly", rootdir + len - 9) == 0) { - rootdir[len - 9] = 0; - } - - /* Append the extension we asked for */ - if (as->parms[2].items) { - strcat(rootdir, as->parms[2].items->data); /* -extension */ - } - - /* The mountpoint root is either specifid in -mountpoint - * or -dir or the current working dir. - */ - if ((as->parms[3].items) || (as->parms[1].items)) { /* -mountpoint or -dir */ - t = (char *)getcwd(thisdir, MAXPATHLEN); /* remember current dir */ - if (!t) { - fprintf(stderr, - "Cannot get pathname of current working directory: %s\n", - thisdir); - code = -1; - goto cleanup; - } - /* Change to the mount point dir */ - code = - chdir((as->parms[3].items ? as->parms[3].items->data : as-> - parms[1].items->data)); - if (code) { - fprintf(stderr, "Mount point directory not found: Error = %d\n", - errno); - goto cleanup; - } - t = (char *)getcwd(mntroot, MAXPATHLEN); /* get its full pathname */ - if (!t) { - fprintf(stderr, - "Cannot determine pathname of mount point root directory: %s\n", - mntroot); - code = -1; - goto cleanup; - } - strcat(mntroot, "/"); /* append '/' to end of it */ - code = chdir(thisdir); /* return to original working dir */ - if (code) { - fprintf(stderr, "Cannot find working directory: Error = %d\n", - errno); - goto cleanup; - } - } else { /* use current directory */ - t = (char *)getcwd(mntroot, MAXPATHLEN); /* get full pathname of current dir */ - if (!t) { - fprintf(stderr, - "Cannot determine pathname of current working directory: %s\n", - mntroot); - code = -1; - goto cleanup; - } - } - strcat(mntroot, "/"); /* append '/' to end of it */ - - /* Set the umask for the restore */ - if (as->parms[4].items) { /* -umask */ - afs_int32 mask; - mask = strtol(as->parms[4].items->data, 0, 8); - fprintf(stderr, "Umask set to 0%03o\n", mask); - umask(mask); - } - - fprintf(stderr, "Restoring volume dump of '%s' to directory '%s'.\n", - dh.volumeName, rootdir); - code = mkdir(rootdir, 0777); - if ((code < 0) && (errno != EEXIST)) { - fprintf(stderr, "Error creating directory %s code=%d;%d\n", rootdir, - code, errno); - } - - for (count = 1; type == 2; count++) { - type = ReadVolumeHeader(count); - for (vcount = 1; type == 3; vcount++) - type = ReadVNode(vcount); - } - - if (type != 4) { - fprintf(stderr, "Expected End-of-Dump\n"); - code = -1; - goto cleanup; - } - - cleanup: - /* For incremental restores, Follow each directory link and - * remove an "AFSFile" links. - */ - if (inc_dump) { - fprintf(stderr, "An incremental dump.\n"); - dirP = opendir(rootdir); - while (dirP && (dirE = readdir(dirP))) { - if (strncmp(dirE->d_name, ADIR, strlen(ADIR)) == 0) { - afs_snprintf(name, sizeof name, "%s/%s", rootdir, - dirE->d_name); - dirQ = opendir(name); - while (dirQ && (dirF = readdir(dirQ))) { - if (strncmp(dirF->d_name, AFILE, strlen(AFILE)) == 0) { - afs_snprintf(name, sizeof name, "%s/%s/%s", rootdir, - dirE->d_name, dirF->d_name); - unlink(name); - } - } - closedir(dirQ); - } else if (strncmp(dirE->d_name, AFILE, strlen(AFILE)) == 0) { - afs_snprintf(name, sizeof name, "%s/%s", rootdir, - dirE->d_name); - unlink(name); - } - } - closedir(dirP); - } - - /* Now go through and remove all the directory links */ - dirP = opendir(rootdir); - while (dirP && (dirE = readdir(dirP))) { - if (strncmp(dirE->d_name, ADIR, strlen(ADIR)) == 0) { - afs_snprintf(name, sizeof name, "%s/%s", rootdir, dirE->d_name); - unlink(name); - } - } - closedir(dirP); - - return (code); -} - -main(argc, argv) - int argc; - char **argv; -{ - struct cmd_syndesc *ts; - struct cmd_item *ti; - - setlinebuf(stdout); - - ts = cmd_CreateSyntax(NULL, WorkerBee, NULL, "vldb check"); - cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file"); - cmd_AddParm(ts, "-dir", CMD_SINGLE, CMD_OPTIONAL, "restore dir"); - cmd_AddParm(ts, "-extension", CMD_SINGLE, CMD_OPTIONAL, "name extension"); - cmd_AddParm(ts, "-mountpoint", CMD_SINGLE, CMD_OPTIONAL, - "mount point root"); - cmd_AddParm(ts, "-umask", CMD_SINGLE, CMD_OPTIONAL, "mode mask"); - - return cmd_Dispatch(argc, argv); -} diff --git a/src/volser/vol.h b/src/volser/vol.h deleted file mode 100644 index 522fb97ee..000000000 --- a/src/volser/vol.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 - */ - -/* - * Module: Vol.h - * System: Volser - * Instituition: ITC, CMU - * Date: December, 88 - */ - -/* pick up the declaration of Inode */ -#include - -typedef struct DirHandle { - int dirh_volume; - int dirh_device; - Inode dirh_inode; - afs_int32 dirh_cacheCheck; - IHandle_t *dirh_handle; -} DirHandle; diff --git a/src/volser/volerr.et b/src/volser/volerr.et deleted file mode 100644 index 16db9f0c0..000000000 --- a/src/volser/volerr.et +++ /dev/null @@ -1,32 +0,0 @@ -# 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 - -# */ - -# NOTE: VOLSERBAD_ACCESS value is hardcoded in audit/audit.h, so if you -# make changes here, make sure that audit/audit.h is kept up to date. - -error_table VOLS - ec VOLSERTRELE_ERROR, "internal error releasing transaction" - ec VOLSERNO_OP, "unknown internal error" - ec VOLSERREAD_DUMPERROR, "badly formatted dump" - ec VOLSERDUMPERROR, "badly formatted dump(2)" - ec VOLSERATTACH_ERROR, "could not attach volume" - ec VOLSERILLEGAL_PARTITION, "illegal partition" - ec VOLSERDETACH_ERROR, "could not detach volume" - ec VOLSERBAD_ACCESS, "insufficient privilege for volume operation" - ec VOLSERVLDB_ERROR, "error from volume location database" - ec VOLSERBADNAME, "bad volume name" - ec VOLSERVOLMOVED, "volume moved" - ec VOLSERBADOP, "illegal volume operation" - ec VOLSERBADRELEASE, "volume release failed" - ec VOLSERVOLBUSY, "volume still in use by volserver" - ec VOLSERNO_MEMORY, "out of virtual memory in volserver" - ec VOLSERNOVOL, "no such volume" - ec VOLSERMULTIRWVOL, "more than one read/write volume" - ec VOLSERFAILEDOP, "failed volume server operation" -end diff --git a/src/volser/volint.xg b/src/volser/volint.xg deleted file mode 100644 index cfa515596..000000000 --- a/src/volser/volint.xg +++ /dev/null @@ -1,410 +0,0 @@ -/* - * 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 - */ - -/* - * Module: Volint.xg - * System: Volser - * Instituition: ITC, CMU - * Date: December, 88 - */ - -package AFSVol -prefix S -statindex 16 - -#define VOLCREATEVOLUME 100 -#define VOLDELETEVOLUME 101 -#define VOLRESTORE 102 -#define VOLFORWARD 103 -#define VOLENDTRANS 104 -#define VOLCLONE 105 -#define VOLSETFLAGS 106 -#define VOLGETFLAGS 107 -#define VOLTRANSCREATE 108 -#define VOLDUMP 109 -#define VOLGETNTHVOLUME 110 -#define VOLSETFORWARDING 111 /* defunct */ -#define VOLGETNAME 112 -#define VOLGETSTATUS 113 -#define VOLSIGRESTORE 114 -#define VOLLISTPARTITIONS 115 -#define VOLLISTVOLS 116 -#define VOLSETIDSTYPES 117 -#define VOLMONITOR 118 -#define VOLDISKPART 119 -#define VOLRECLONE 120 -#define VOLLISTONEVOL 121 -#define VOLNUKE 122 -#define VOLSETDATE 123 -#define VOLXLISTVOLS 124 -#define VOLXLISTONEVOL 125 -#define VOLSETINFO 126 -#define VOLXLISTPARTITIONS 127 -#define VOLFORWARDMULTIPLE 128 -#define VOLCONVERTRO 65536 -#define VOLGETSIZE 65537 - -const SIZE = 1024; - -struct volser_status { - afs_int32 volID; /* Volume id--unique over all systems */ - afs_int32 nextUnique; /* Next vnode uniquifier for this volume */ - int type; /* readwrite, etc. */ - afs_int32 parentID; /* Id of parent, if type==readonly or backup */ - afs_int32 cloneID; /* Latest read-only clone, if type==readwrite */ - afs_int32 backupID; /* Latest backup copy of this read write volume */ - afs_int32 restoredFromID; /* The id in a dump this volume was restored from--used simply - to make sure that an incremental dump is not restored on top - of something inappropriate: Note: this field itself is NEVER - dumped!!! */ - afs_int32 maxQuota; /* Quota maximum, 1K blocks */ - afs_int32 minQuota; /* Quota minimum, 1K blocks */ - afs_int32 owner; /* The person responsible for this volume */ - afs_int32 creationDate; /* Creation date for a read/write - volume; cloning date for original copy of - a readonly volume (replicated volumes have - the same creation date) */ - afs_int32 accessDate; /* Last access time by a user, large granularity */ - afs_int32 updateDate; /* Last modification by user */ - afs_int32 expirationDate; /* 0 if it never expires */ - afs_int32 backupDate; /* last time a backup clone was taken */ - afs_int32 copyDate; /* Time that this copy of this volume was created */ -}; - -struct destServer { - afs_int32 destHost; - afs_int32 destPort; - afs_int32 destSSID; -}; - - -struct volintInfo { -#define VNAMESIZE 32 - char name[VNAMESIZE]; - afs_int32 volid; /* volume's id */ - afs_int32 type; /* read-only, read-write, backup */ - afs_int32 backupID; - afs_int32 parentID; - afs_int32 cloneID; - afs_int32 status; - afs_int32 copyDate; - unsigned char inUse; - unsigned char needsSalvaged; - unsigned char destroyMe; - afs_int32 creationDate; - afs_int32 accessDate; - afs_int32 updateDate; - afs_int32 backupDate; - int dayUse; - int filecount; - int maxquota; - int size; - afs_int32 flags; /* used by the backup system */ - afs_int32 spare0; /* Used to hold the minquota value */ - afs_int32 spare1; /* Used to hold the weekuse value */ - afs_int32 spare2; - afs_int32 spare3; -}; - -/* - * Define some values needed for the detailed volume info structure. - */ -const VOLINT_STATS_NUM_RWINFO_FIELDS = 4; - -const VOLINT_STATS_SAME_NET = 0; /*Within same site (total)*/ -const VOLINT_STATS_SAME_NET_AUTH = 1; /*Within same site (authenticated); - (must be 1 more than above)*/ -const VOLINT_STATS_DIFF_NET = 2; /*From external site (total)*/ -const VOLINT_STATS_DIFF_NET_AUTH = 3; /*From external site (authenticated) - (must be 1 more than above)*/ - -const VOLINT_STATS_NUM_TIME_RANGES = 6; - -const VOLINT_STATS_TIME_CAP_0 = 60; /*60 seconds*/ -const VOLINT_STATS_TIME_CAP_1 = 600; /*10 minutes, in seconds*/ -const VOLINT_STATS_TIME_CAP_2 = 3600; /*1 hour, in seconds*/ -const VOLINT_STATS_TIME_CAP_3 = 86400; /*1 day, in seconds*/ -const VOLINT_STATS_TIME_CAP_4 = 604800; /*1 week, in seconds*/ - -const VOLINT_STATS_NUM_TIME_FIELDS = 6; - -const VOLINT_STATS_TIME_IDX_0 = 0; /*0 secs to 60 secs*/ -const VOLINT_STATS_TIME_IDX_1 = 1; /*1 min to 10 mins*/ -const VOLINT_STATS_TIME_IDX_2 = 2; /*10 mins to 60 mins*/ -const VOLINT_STATS_TIME_IDX_3 = 3; /*1 hr to 24 hrs*/ -const VOLINT_STATS_TIME_IDX_4 = 4; /*1 day to 7 days*/ -const VOLINT_STATS_TIME_IDX_5 = 5; /*Greater than 1 week*/ - -/* - * More detailed volume info - */ -struct volintXInfo { - char name[VNAMESIZE]; - afs_int32 volid; /*Volume's ID*/ - afs_int32 type; /*RWVOL, ROVOL, BACKVOL*/ - afs_int32 backupID; /*Backup volume ID*/ - afs_int32 parentID; /*Parent volume ID*/ - afs_int32 cloneID; /*Clone volume ID*/ - afs_int32 status; /*Volume status*/ - afs_int32 copyDate; /*Date when this volume INSTANCE created*/ - unsigned char inUse; /*In use at time of last crash?*/ - afs_int32 creationDate; /*Date when this volume was created*/ - afs_int32 accessDate; /*Date when this volume was last accessed*/ - afs_int32 updateDate; /*Date when this volume was last updated*/ - afs_int32 backupDate; /*Date when this volume was last backed up*/ - int dayUse; /*Number of accesses since midnight*/ - int filecount; /*Number of files in the volume*/ - int maxquota; /*Max volume quota, in Kbytes*/ - int size; /*Current size in Kbytes*/ - /* - * Detailed statistics for reads/writes and authorship. - */ - afs_int32 stat_reads[VOLINT_STATS_NUM_RWINFO_FIELDS]; - afs_int32 stat_writes[VOLINT_STATS_NUM_RWINFO_FIELDS]; - afs_int32 stat_fileSameAuthor[VOLINT_STATS_NUM_TIME_FIELDS]; - afs_int32 stat_fileDiffAuthor[VOLINT_STATS_NUM_TIME_FIELDS]; - afs_int32 stat_dirSameAuthor[VOLINT_STATS_NUM_TIME_FIELDS]; - afs_int32 stat_dirDiffAuthor[VOLINT_STATS_NUM_TIME_FIELDS]; -}; - -struct transDebugInfo { - afs_int32 tid; /*transaction id */ - afs_int32 time; /* time transaction was last active (for timeouts) */ - afs_int32 creationTime; /* time the transaction started */ - afs_int32 returnCode; /* transaction error code */ - afs_int32 volid; /*sequence number of the next packet to be read*/ /* open volume's id */ - afs_int32 partition; /* open volume's partition */ - short iflags; /* initial attach mode flags (IT*) */ - char vflags; /* current volume status flags (VT*) */ - char tflags; /* transaction flags (TT*) */ - char lastProcName[30]; /* name of the last procedure which used transaction */ - int callValid; /*flag which determines if following data is valid*/ - afs_int32 readNext; /*sequence number of the next packet to be read*/ - afs_int32 transmitNext; /*sequence number of the next packet to be transmitted*/ - int lastSendTime; - int lastReceiveTime; -}; - -struct pIDs { - afs_int32 partIds[26]; -}; - -struct diskPartition { - char name[32]; /* Mounted partition name */ - char devName[32]; - int lock_fd; - int totalUsable; - int free; - int minFree; - -}; - -struct restoreCookie { - char name[32]; - afs_int32 type; - afs_int32 clone; - afs_int32 parent; -}; - -struct replica { - afs_int32 trans; - struct destServer server; -}; - -/* Various size parameters of the volume */ -struct volintSize { - afs_uint64 dump_size; -}; - -typedef replica manyDests<>; -typedef afs_int32 manyResults<>; -typedef transDebugInfo transDebugEntries<>; -typedef volintInfo volEntries<>; -typedef afs_int32 partEntries<>; -typedef volintXInfo volXEntries<>; - -proc CreateVolume( - IN afs_int32 partition, - string name<>, - IN afs_int32 type, - IN afs_int32 parent, - INOUT afs_int32 *volid, - OUT afs_int32 *trans -) = VOLCREATEVOLUME; - -proc DeleteVolume( - IN afs_int32 trans -) = VOLDELETEVOLUME; - -proc Restore( - IN afs_int32 toTrans, - IN afs_int32 flags, - IN struct restoreCookie *cookie -) split = VOLRESTORE; - -proc Forward( - IN afs_int32 fromTrans, - IN afs_int32 fromDate, - IN struct destServer *destination, - IN afs_int32 destTrans, - IN struct restoreCookie *cookie -) = VOLFORWARD; - -proc EndTrans( - IN afs_int32 trans, - OUT afs_int32 *rcode -) = VOLENDTRANS; - -proc Clone( - IN afs_int32 trans, - IN afs_int32 purgeVol, - IN afs_int32 newType, - IN string newName<>, - INOUT afs_int32 *newVol -) = VOLCLONE; - -proc SetFlags( - IN afs_int32 trans, - IN afs_int32 flags -) = VOLSETFLAGS; - -proc GetFlags( - IN afs_int32 trans, - OUT afs_int32 *flags -) = VOLGETFLAGS; - -proc TransCreate( - IN afs_int32 volume, - IN afs_int32 partition, - IN afs_int32 flags, - OUT afs_int32 *trans -) = VOLTRANSCREATE; - -proc Dump( - IN afs_int32 fromTrans, - IN afs_int32 fromDate -) split = VOLDUMP; - -proc GetNthVolume( - IN afs_int32 index, - OUT afs_int32 *volume, - OUT afs_int32 *partition -) = VOLGETNTHVOLUME; - -proc SetForwarding( - IN afs_int32 tid, - IN afs_int32 newsite -) = VOLSETFORWARDING; - -proc GetName( - IN afs_int32 tid, - OUT string tname<256> -) = VOLGETNAME; - -proc GetStatus( - IN afs_int32 tid, - OUT struct volser_status *status -) = VOLGETSTATUS; - -proc SignalRestore( - IN string name<>, - int type, - afs_int32 pid, - afs_int32 cloneid -) = VOLSIGRESTORE; - -proc ListPartitions( - OUT struct pIDs *partIDs -) = VOLLISTPARTITIONS; - -proc ListVolumes( - IN afs_int32 partID, - afs_int32 flags, - OUT volEntries *resultEntries -) = VOLLISTVOLS; - -proc SetIdsTypes( - IN afs_int32 tId, - string name<>, - afs_int32 type, - afs_int32 pId, - afs_int32 cloneId, - afs_int32 backupId -) = VOLSETIDSTYPES; - -proc Monitor( - OUT transDebugEntries *result -) = VOLMONITOR; - -proc PartitionInfo( - IN string name<>, - OUT struct diskPartition *partition -) = VOLDISKPART; - -proc ReClone( - IN afs_int32 tid, - afs_int32 cloneID -) = VOLRECLONE; - -proc ListOneVolume( - IN afs_int32 partID, - afs_int32 volid, - OUT volEntries *resultEntries -) = VOLLISTONEVOL; - -proc NukeVolume( - IN afs_int32 partID, - afs_int32 volID -) = VOLNUKE; - -proc SetDate( - IN afs_int32 tid, - afs_int32 newDate -) = VOLSETDATE; - -proc XListVolumes( - IN afs_int32 partID, - afs_int32 flags, - OUT volXEntries *resultXEntriesP -) = VOLXLISTVOLS; - -proc XListOneVolume( - IN afs_int32 partID, - afs_int32 volid, - OUT volXEntries *resultXEntries -) = VOLXLISTONEVOL; - -proc SetInfo( - IN afs_int32 tid, - struct volintInfo *status -) = VOLSETINFO; - -proc XListPartitions( - OUT struct partEntries *partIDs -) = VOLXLISTPARTITIONS; - -proc ForwardMultiple( - IN afs_int32 fromTrans, - IN afs_int32 fromDate, - IN manyDests *destinations, - IN afs_int32 spare, - IN struct restoreCookie *cookie, - OUT manyResults *results -) = VOLFORWARDMULTIPLE; - -proc ConvertROtoRWvolume( - IN afs_int32 partid, - IN afs_int32 volid -) = VOLCONVERTRO; - -proc GetSize( - IN afs_int32 fromTrans, - IN afs_int32 fromDate, - OUT struct volintSize *size -) = VOLGETSIZE; diff --git a/src/volser/volmain.c b/src/volser/volmain.c deleted file mode 100644 index 237d32ea6..000000000 --- a/src/volser/volmain.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * 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 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/volmain.c,v 1.18 2003/12/07 22:49:44 jaltman Exp $"); - -#include -#ifdef AFS_NT40_ENV -#include -#include -#include -#include -#else -#include -#include -#include -#endif -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif -#include -#include -#include -#include -#ifdef AFS_PTHREAD_ENV -#include -#else /* AFS_PTHREAD_ENV */ -#include -#endif /* AFS_PTHREAD_ENV */ -#include -#include -#include -#include -#include -#include -#ifdef AFS_NT40_ENV -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "volser.h" -#include -#include -#include - -/*@printflike@*/ extern void Log(const char *format, ...); -/*@printflike@*/ extern void Abort(const char *format, ...); - -#define VolserVersion "2.0" -#define N_SECURITY_OBJECTS 3 - -extern struct volser_trans *TransList(); -#ifndef AFS_PTHREAD_ENV -extern int (*vol_PollProc) (); -extern int IOMGR_Poll(); -#endif -char *GlobalNameHack = NULL; -int hackIsIn = 0; -afs_int32 GlobalVolCloneId, GlobalVolParentId; -int GlobalVolType; -int VolumeChanged; /* XXXX */ -static char busyFlags[MAXHELPERS]; -struct volser_trans *QI_GlobalWriteTrans = 0; -extern void AFSVolExecuteRequest(); -extern void RXSTATS_ExecuteRequest(); -struct afsconf_dir *tdir; -static afs_int32 runningCalls = 0; -int DoLogging = 0; -#define MAXLWP 16 -int lwps = 9; -int udpBufSize = 0; /* UDP buffer size for receive */ - -int Testing = 0; /* for ListViceInodes */ - -#define VS_EXIT(code) { \ - osi_audit(VS_ExitEvent, code, AUD_END); \ - exit(code); \ - } - - -static -MyBeforeProc(struct rx_call *acall) -{ - VTRANS_LOCK; - runningCalls++; - VTRANS_UNLOCK; - return 0; -} - -static -MyAfterProc(struct rx_call *acall, afs_int32 code) -{ - VTRANS_LOCK; - runningCalls--; - VTRANS_UNLOCK; - return 0; -} - -/* Called every GCWAKEUP seconds to try to unlock all our partitions, - * if we're idle and there are no active transactions - */ -static -TryUnlock() -{ - /* if there are no running calls, and there are no active transactions, then - * it should be safe to release any partition locks we've accumulated */ - VTRANS_LOCK; - if (runningCalls == 0 && TransList() == (struct volser_trans *)0) { - VTRANS_UNLOCK; - VPFullUnlock(); /* in volprocs.c */ - } else - VTRANS_UNLOCK; -} - -/* background daemon for timing out transactions */ -static -BKGLoop() -{ - struct timeval tv; - int loop = 0; - - while (1) { - tv.tv_sec = GCWAKEUP; - tv.tv_usec = 0; -#ifdef AFS_PTHREAD_ENV - select(0, 0, 0, 0, &tv); -#else - (void)IOMGR_Select(0, 0, 0, 0, &tv); -#endif - GCTrans(); - TryUnlock(); - loop++; - if (loop == 10) { /* reopen log every 5 minutes */ - loop = 0; - ReOpenLog(AFSDIR_SERVER_VOLSERLOG_FILEPATH); - } - } -} - -/* Background daemon for sleeping so the volserver does not become I/O bound */ -afs_int32 TTsleep, TTrun; -static -BKGSleep() -{ - struct volser_trans *tt; - - if (TTsleep) { - while (1) { -#ifdef AFS_PTHREAD_ENV - sleep(TTrun); -#else /* AFS_PTHREAD_ENV */ - IOMGR_Sleep(TTrun); -#endif - VTRANS_LOCK; - for (tt = TransList(); tt; tt = tt->next) { - if ((strcmp(tt->lastProcName, "DeleteVolume") == 0) - || (strcmp(tt->lastProcName, "Clone") == 0) - || (strcmp(tt->lastProcName, "ReClone") == 0) - || (strcmp(tt->lastProcName, "Forward") == 0) - || (strcmp(tt->lastProcName, "Restore") == 0) - || (strcmp(tt->lastProcName, "ForwardMulti") == 0)) - break; - } - if (tt) { - VTRANS_UNLOCK; - sleep(TTsleep); - } else - VTRANS_UNLOCK; - } - } -} - -#ifndef AFS_NT40_ENV -int -volser_syscall(a3, a4, a5) - afs_uint32 a3, a4; - void *a5; -{ - afs_uint32 rcode; - void (*old) (); - -#ifndef AFS_LINUX20_ENV - old = signal(SIGSYS, SIG_IGN); -#endif - rcode = - syscall(AFS_SYSCALL /* AFS_SYSCALL */ , 28 /* AFSCALL_CALL */ , a3, - a4, a5); -#ifndef AFS_LINUX20_ENV - signal(SIGSYS, old); -#endif - - return rcode; -} -#endif - - -/* check whether caller is authorized to manage RX statistics */ -int -vol_rxstat_userok(call) - struct rx_call *call; -{ - return afsconf_SuperUser(tdir, call, NULL); -} - -#include "AFS_component_version_number.c" -main(argc, argv) - int argc; - char **argv; -{ - register afs_int32 code; - struct rx_securityClass *(securityObjects[3]); - struct rx_service *service; - struct ktc_encryptionKey tkey; - int rxpackets = 100; - char commandLine[150]; - int i; - int rxJumbograms = 1; /* default is to send and receive jumbograms. */ - int bufSize = 0; /* temp variable to read in udp socket buf size */ - -#ifdef AFS_AIX32_ENV - /* - * The following signal action for AIX is necessary so that in case of a - * crash (i.e. core is generated) we can include the user's data section - * in the core dump. Unfortunately, by default, only a partial core is - * generated which, in many cases, isn't too useful. - */ - struct sigaction nsa; - - sigemptyset(&nsa.sa_mask); - nsa.sa_handler = SIG_DFL; - nsa.sa_flags = SA_FULLDUMP; - sigaction(SIGABRT, &nsa, NULL); - sigaction(SIGSEGV, &nsa, NULL); -#endif - osi_audit(VS_StartEvent, 0, AUD_END); - - /* Initialize dirpaths */ - if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { -#ifdef AFS_NT40_ENV - ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); -#endif - fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", - argv[0]); - exit(2); - } - - for (commandLine[0] = '\0', i = 0; i < argc; i++) { - if (i > 0) - strcat(commandLine, " "); - strcat(commandLine, argv[i]); - } - - TTsleep = TTrun = 0; - - /* parse cmd line */ - for (code = 1; code < argc; code++) { - if (strcmp(argv[code], "-log") == 0) { - /* set extra logging flag */ - DoLogging = 1; - } else if (strcmp(argv[code], "-help") == 0) { - goto usage; - } else if (strcmp(argv[code], "-p") == 0) { - lwps = atoi(argv[++code]); - if (lwps > MAXLWP) { - printf("Warning: '-p %d' is too big; using %d instead\n", - lwps, MAXLWP); - lwps = MAXLWP; - } - } else if (strcmp(argv[code], "-nojumbo") == 0) { - rxJumbograms = 0; - } else if (strcmp(argv[code], "-sleep") == 0) { - sscanf(argv[++code], "%d/%d", &TTsleep, &TTrun); - if ((TTsleep < 0) || (TTrun <= 0)) { - printf("Warning: '-sleep %d/%d' is incorrect; ignoring\n", - TTsleep, TTrun); - TTsleep = TTrun = 0; - } - } else if (strcmp(argv[code], "-udpsize") == 0) { - if ((code + 1) >= argc) { - printf("You have to specify -udpsize \n"); - exit(1); - } - sscanf(argv[++code], "%d", &bufSize); - if (bufSize < rx_GetMinUdpBufSize()) - printf - ("Warning:udpsize %d is less than minimum %d; ignoring\n", - bufSize, rx_GetMinUdpBufSize()); - else - udpBufSize = bufSize; - } else if (strcmp(argv[code], "-enable_peer_stats") == 0) { - rx_enablePeerRPCStats(); - } else if (strcmp(argv[code], "-enable_process_stats") == 0) { - rx_enableProcessRPCStats(); - } -#ifndef AFS_NT40_ENV - else if (strcmp(argv[code], "-syslog") == 0) { - /* set syslog logging flag */ - serverLogSyslog = 1; - } else if (strncmp(argv[code], "-syslog=", 8) == 0) { - serverLogSyslog = 1; - serverLogSyslogFacility = atoi(argv[code] + 8); - } -#endif - else { - printf("volserver: unrecognized flag '%s'\n", argv[code]); - usage: -#ifndef AFS_NT40_ENV - printf("Usage: volserver [-log] [-p ] " - "[-udpsize ] " - "[-syslog[=FACILITY]] " - "[-enable_peer_stats] [-enable_process_stats] " - "[-help]\n"); -#else - printf("Usage: volserver [-log] [-p ] " - "[-udpsize ] " - "[-enable_peer_stats] [-enable_process_stats] " - "[-help]\n"); -#endif - VS_EXIT(1); - } - } -#ifdef AFS_SGI_VNODE_GLUE - if (afs_init_kernel_config(-1) < 0) { - printf - ("Can't determine NUMA configuration, not starting volserver.\n"); - exit(1); - } -#endif - InitErrTabs(); - -#ifdef AFS_NT40_ENV - if (afs_winsockInit() < 0) { - ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); - printf("Volume server unable to start winsock, exiting.\n"); - exit(1); - } -#endif - VInitVolumePackage(volumeUtility, 0, 0, CONNECT_FS, 0); - DInit(40); -#ifndef AFS_PTHREAD_ENV - vol_PollProc = IOMGR_Poll; /* tell vol pkg to poll io system periodically */ -#endif -#ifndef AFS_NT40_ENV - rxi_syscallp = volser_syscall; -#endif - rx_nPackets = rxpackets; /* set the max number of packets */ - if (udpBufSize) - rx_SetUdpBufSize(udpBufSize); /* set the UDP buffer size for receive */ - code = rx_Init((int)htons(AFSCONF_VOLUMEPORT)); - if (code) { - fprintf(stderr, "rx init failed on socket AFSCONF_VOLUMEPORT %u\n", - AFSCONF_VOLUMEPORT); - VS_EXIT(1); - } - if (!rxJumbograms) { - /* Don't allow 3.4 vos clients to send jumbograms and we don't send. */ - rx_SetNoJumbo(); - } - rx_GetIFInfo(); - rx_SetRxDeadTime(420); - memset(busyFlags, 0, sizeof(busyFlags)); - - /* Open FileLog and map stdout, stderr into it */ - OpenLog(AFSDIR_SERVER_VOLSERLOG_FILEPATH); - SetupLogSignals(); - - { -#ifdef AFS_PTHREAD_ENV - pthread_t tid; - pthread_attr_t tattr; - assert(pthread_attr_init(&tattr) == 0); - assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0); - - assert(pthread_create(&tid, &tattr, (void *)BKGLoop, NULL) == 0); -#else - PROCESS pid; - LWP_CreateProcess(BKGLoop, 16*1024, 3, 0, "vol bkg daemon", &pid); - LWP_CreateProcess(BKGSleep,16*1024, 3, 0, "vol slp daemon", &pid); -#endif - } - - /* Create a single security object, in this case the null security object, for unauthenticated connections, which will be used to control security on connections made to this server */ - - tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); - if (!tdir) { - Abort("volser: could not open conf files in %s\n", - AFSDIR_SERVER_ETC_DIRPATH); - VS_EXIT(1); - } - afsconf_GetKey(tdir, 999, &tkey); - securityObjects[0] = rxnull_NewServerSecurityObject(); - securityObjects[1] = (struct rx_securityClass *)0; /* don't bother with rxvab */ - securityObjects[2] = - rxkad_NewServerSecurityObject(0, tdir, afsconf_GetKey, NULL); - if (securityObjects[0] == (struct rx_securityClass *)0) - Abort("rxnull_NewServerSecurityObject"); - service = - rx_NewService(0, VOLSERVICE_ID, "VOLSER", securityObjects, 3, - AFSVolExecuteRequest); - if (service == (struct rx_service *)0) - Abort("rx_NewService"); - rx_SetBeforeProc(service, MyBeforeProc); - rx_SetAfterProc(service, MyAfterProc); - rx_SetIdleDeadTime(service, 0); /* never timeout */ - if (lwps < 4) - lwps = 4; - rx_SetMaxProcs(service, lwps); -#ifdef AFS_SGI_ENV - rx_SetStackSize(service, 49152); -#else - rx_SetStackSize(service, 32768); -#endif - - service = - rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", securityObjects, 3, - RXSTATS_ExecuteRequest); - if (service == (struct rx_service *)0) - Abort("rx_NewService"); - rx_SetMinProcs(service, 2); - rx_SetMaxProcs(service, 4); - - Log("Starting AFS Volserver %s (%s)\n", VolserVersion, commandLine); - if (TTsleep) { - Log("Will sleep %d second%s every %d second%s\n", TTsleep, - (TTsleep > 1) ? "s" : "", TTrun + TTsleep, - (TTrun + TTsleep > 1) ? "s" : ""); - } - - /* allow super users to manage RX statistics */ - rx_SetRxStatUserOk(vol_rxstat_userok); - - rx_StartServer(1); /* Donate this process to the server process pool */ - - osi_audit(VS_FinishEvent, (-1), AUD_END); - Abort("StartServer returned?"); -} diff --git a/src/volser/volprocs.c b/src/volser/volprocs.c deleted file mode 100644 index 433a7a618..000000000 --- a/src/volser/volprocs.c +++ /dev/null @@ -1,2908 +0,0 @@ -/* - * 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 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.33 2004/01/01 06:22:31 shadow Exp $"); - -#include -#include -#include -#ifdef AFS_NT40_ENV -#include -#include -#else -#include -#include -#include -#endif - -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#ifdef AFS_PTHREAD_ENV -#include -#else /* AFS_PTHREAD_ENV */ -#include -#endif /* AFS_PTHREAD_ENV */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef AFS_NT40_ENV -#include -#endif -#include -#include -#include -#include "vol.h" -#include -#include -#include "afs/audit.h" -#include - -#include "volser.h" -#include "volint.h" - -#include "volser_prototypes.h" - -extern int DoLogging; -extern struct volser_trans *FindTrans(), *NewTrans(), *TransList(); -extern struct afsconf_dir *tdir; - -/* Needed by Irix. Leave, or include a header */ -extern char *volutil_PartitionName(); - -extern void LogError(afs_int32 errcode); - -/* Forward declarations */ -static int GetPartName(afs_int32 partid, char *pname); - -#define OneDay (24*60*60) - -#ifdef AFS_NT40_ENV -#define ENOTCONN 134 -#endif - -afs_int32 localTid = 1; -afs_int32 VolPartitionInfo(), VolNukeVolume(), VolCreateVolume(), -VolDeleteVolume(), VolClone(); -afs_int32 VolReClone(), VolTransCreate(), VolGetNthVolume(), VolGetFlags(), -VolForward(), VolDump(); -afs_int32 VolRestore(), VolEndTrans(), VolSetForwarding(), VolGetStatus(), -VolSetInfo(), VolGetName(); -afs_int32 VolListPartitions(), VolListOneVolume(), -VolXListOneVolume(), VolXListVolumes(); -afs_int32 VolListVolumes(), XVolListPartitions(), VolMonitor(), -VolSetIdsTypes(), VolSetDate(), VolSetFlags(); - -/* this call unlocks all of the partition locks we've set */ -int -VPFullUnlock() -{ - register struct DiskPartition *tp; - for (tp = DiskPartitionList; tp; tp = tp->next) { - if (tp->lock_fd != -1) { - close(tp->lock_fd); /* releases flock held on this partition */ - tp->lock_fd = -1; - } - } - return 0; -} - -/* get partition id from a name */ -afs_int32 -PartitionID(char *aname) -{ - register char tc; - register int code = 0; - char ascii[3]; - - tc = *aname; - if (tc == 0) - return -1; /* unknown */ - - /* otherwise check for vicepa or /vicepa, or just plain "a" */ - ascii[2] = 0; - if (!strncmp(aname, "/vicep", 6)) { - strncpy(ascii, aname + 6, 2); - } else - return -1; /* bad partition name */ - /* now partitions are named /vicepa ... /vicepz, /vicepaa, /vicepab, .../vicepzz, and are numbered - * from 0. Do the appropriate conversion */ - if (ascii[1] == 0) { - /* one char name, 0..25 */ - if (ascii[0] < 'a' || ascii[0] > 'z') - return -1; /* wrongo */ - return ascii[0] - 'a'; - } else { - /* two char name, 26 .. */ - if (ascii[0] < 'a' || ascii[0] > 'z') - return -1; /* wrongo */ - if (ascii[1] < 'a' || ascii[1] > 'z') - return -1; /* just as bad */ - code = (ascii[0] - 'a') * 26 + (ascii[1] - 'a') + 26; - if (code > VOLMAXPARTS) - return -1; - return code; - } -} - -static int -ConvertVolume(afs_int32 avol, char *aname, afs_int32 asize) -{ - if (asize < 18) - return -1; - /* It's better using the Generic VFORMAT since otherwise we have to make changes to too many places... The 14 char limitation in names hits us again in AIX; print in field of 9 digits (still 10 for the rest), right justified with 0 padding */ - (void)afs_snprintf(aname, asize, VFORMAT, (unsigned long)avol); - return 0; -} - -static int -ConvertPartition(int apartno, char *aname, int asize) -{ - if (asize < 10) - return E2BIG; - if (apartno < 0) - return EINVAL; - strcpy(aname, "/vicep"); - if (apartno < 26) { - aname[6] = 'a' + apartno; - aname[7] = 0; - } else { - apartno -= 26; - aname[6] = 'a' + (apartno / 26); - aname[7] = 'a' + (apartno % 26); - aname[8] = 0; - } - return 0; -} - -/* the only attach function that takes a partition is "...ByName", so we use it */ -struct Volume * -XAttachVolume(afs_int32 *error, afs_int32 avolid, afs_int32 apartid, int amode) -{ - char pbuf[30], vbuf[20]; - register struct Volume *tv; - - if (ConvertPartition(apartid, pbuf, sizeof(pbuf))) { - *error = EINVAL; - return NULL; - } - if (ConvertVolume(avolid, vbuf, sizeof(vbuf))) { - *error = EINVAL; - return NULL; - } - tv = VAttachVolumeByName(error, pbuf, vbuf, amode); - return tv; -} - -/* Adapted from the file server; create a root directory for this volume */ -static int -ViceCreateRoot(Volume *vp) -{ - DirHandle dir; - struct acl_accessList *ACL; - ViceFid did; - Inode inodeNumber, nearInode; - char buf[SIZEOF_LARGEDISKVNODE]; - struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf; - struct VnodeClassInfo *vcp = &VnodeClassInfo[vLarge]; - IHandle_t *h; - FdHandle_t *fdP; - int code; - afs_fsize_t length; - - memset(vnode, 0, SIZEOF_LARGEDISKVNODE); - - V_pref(vp, nearInode); - inodeNumber = - IH_CREATE(V_linkHandle(vp), V_device(vp), - VPartitionPath(V_partition(vp)), nearInode, V_parentId(vp), - 1, 1, 0); - assert(VALID_INO(inodeNumber)); - - SetSalvageDirHandle(&dir, V_parentId(vp), vp->device, inodeNumber); - did.Volume = V_id(vp); - did.Vnode = (VnodeId) 1; - did.Unique = 1; - - assert(!(MakeDir(&dir, &did, &did))); - DFlush(); /* flush all modified dir buffers out */ - DZap(&dir); /* Remove all buffers for this dir */ - length = Length(&dir); /* Remember size of this directory */ - - FidZap(&dir); /* Done with the dir handle obtained via SetSalvageDirHandle() */ - - /* build a single entry ACL that gives all rights to system:administrators */ - /* this section of code assumes that access list format is not going to - * change - */ - ACL = VVnodeDiskACL(vnode); - ACL->size = sizeof(struct acl_accessList); - ACL->version = ACL_ACLVERSION; - ACL->total = 1; - ACL->positive = 1; - ACL->negative = 0; - ACL->entries[0].id = -204; /* this assumes System:administrators is group -204 */ - ACL->entries[0].rights = - PRSFS_READ | PRSFS_WRITE | PRSFS_INSERT | PRSFS_LOOKUP | PRSFS_DELETE - | PRSFS_LOCK | PRSFS_ADMINISTER; - - vnode->type = vDirectory; - vnode->cloned = 0; - vnode->modeBits = 0777; - vnode->linkCount = 2; - VNDISK_SET_LEN(vnode, length); - vnode->uniquifier = 1; - V_uniquifier(vp) = vnode->uniquifier + 1; - vnode->dataVersion = 1; - VNDISK_SET_INO(vnode, inodeNumber); - vnode->unixModifyTime = vnode->serverModifyTime = V_creationDate(vp); - vnode->author = 0; - vnode->owner = 0; - vnode->parent = 0; - vnode->vnodeMagic = vcp->magic; - - IH_INIT(h, vp->device, V_parentId(vp), - vp->vnodeIndex[vLarge].handle->ih_ino); - fdP = IH_OPEN(h); - assert(fdP != NULL); - code = FDH_SEEK(fdP, vnodeIndexOffset(vcp, 1), SEEK_SET); - assert(code >= 0); - code = FDH_WRITE(fdP, vnode, SIZEOF_LARGEDISKVNODE); - assert(code == SIZEOF_LARGEDISKVNODE); - FDH_REALLYCLOSE(fdP); - IH_RELEASE(h); - VNDISK_GET_LEN(length, vnode); - V_diskused(vp) = nBlocks(length); - - return 1; -} - -afs_int32 -SAFSVolPartitionInfo(struct rx_call *acid, char *pname, struct diskPartition - *partition) -{ - afs_int32 code; - - code = VolPartitionInfo(acid, pname, partition); - osi_auditU(acid, VS_ParInfEvent, code, AUD_STR, pname, AUD_END); - return code; -} - -afs_int32 -VolPartitionInfo(struct rx_call *acid, char *pname, struct diskPartition - *partition) -{ - register struct DiskPartition *dp; - -/* - if (!afsconf_SuperUser(tdir, acid, caller)) return VOLSERBAD_ACCESS; -*/ - VResetDiskUsage(); - dp = VGetPartition(pname, 0); - if (dp) { - strncpy(partition->name, dp->name, 32); - strncpy(partition->devName, dp->devName, 32); - partition->lock_fd = dp->lock_fd; - partition->free = dp->free; - partition->minFree = dp->totalUsable; - return 0; - } else - return VOLSERILLEGAL_PARTITION; -} - -/* obliterate a volume completely, and slowly. */ -afs_int32 -SAFSVolNukeVolume(struct rx_call *acid, afs_int32 apartID, afs_int32 avolID) -{ - afs_int32 code; - - code = VolNukeVolume(acid, apartID, avolID); - osi_auditU(acid, VS_NukVolEvent, code, AUD_LONG, avolID, AUD_END); - return code; -} - -afs_int32 -VolNukeVolume(struct rx_call *acid, afs_int32 apartID, afs_int32 avolID) -{ - register char *tp; - char partName[50]; - afs_int32 error; - register afs_int32 code; - struct Volume *tvp; - char caller[MAXKTCNAMELEN]; - - /* check for access */ - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; - if (DoLogging) - Log("%s is executing VolNukeVolume %u\n", caller, avolID); - - tp = volutil_PartitionName(apartID); - if (!tp) - return VOLSERNOVOL; - strcpy(partName, tp); /* remember it for later */ - /* we first try to attach the volume in update mode, so that the file - * server doesn't try to use it (and abort) while (or after) we delete it. - * If we don't get the volume, that's fine, too. We just won't put it back. - */ - tvp = XAttachVolume(&error, avolID, apartID, V_VOLUPD); - code = nuke(partName, avolID); - if (tvp) - VDetachVolume(&error, tvp); - return code; -} - -/* create a new volume, with name aname, on the specified partition (1..n) - * and of type atype (readwriteVolume, readonlyVolume, backupVolume). - * As input, if *avolid is 0, we allocate a new volume id, otherwise we use *avolid - * for the volume id (useful for things like volume restore). - * Return the new volume id in *avolid. - */ -afs_int32 -SAFSVolCreateVolume(struct rx_call *acid, afs_int32 apart, char *aname, - afs_int32 atype, afs_int32 aparent, afs_int32 *avolid, - afs_int32 *atrans) -{ - afs_int32 code; - - code = - VolCreateVolume(acid, apart, aname, atype, aparent, avolid, atrans); - osi_auditU(acid, VS_CrVolEvent, code, AUD_LONG, *atrans, AUD_LONG, - *avolid, AUD_STR, aname, AUD_LONG, atype, AUD_LONG, aparent, - AUD_END); - return code; -} - -afs_int32 -VolCreateVolume(struct rx_call *acid, afs_int32 apart, char *aname, - afs_int32 atype, afs_int32 aparent, afs_int32 *avolid, - afs_int32 *atrans) -{ - afs_int32 error; - register Volume *vp; - afs_int32 junk; /* discardable error code */ - register afs_int32 volumeID, doCreateRoot = 1; - register struct volser_trans *tt; - char ppath[30]; - char caller[MAXKTCNAMELEN]; - - if (strlen(aname) > 31) - return VOLSERBADNAME; - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; - if (DoLogging) - Log("%s is executing CreateVolume '%s'\n", caller, aname); - if ((error = ConvertPartition(apart, ppath, sizeof(ppath)))) - return error; /*a standard unix error */ - if (atype != readwriteVolume && atype != readonlyVolume - && atype != backupVolume) - return EINVAL; - if ((volumeID = *avolid) == 0) { - - Log("1 Volser: CreateVolume: missing volume number; %s volume not created\n", aname); - return E2BIG; - - } - if ((aparent == volumeID) && (atype == readwriteVolume)) { - doCreateRoot = 0; - } - if (aparent == 0) - aparent = volumeID; - tt = NewTrans(volumeID, apart); - if (!tt) { - Log("1 createvolume: failed to create trans\n"); - return VOLSERVOLBUSY; /* volume already busy! */ - } - vp = VCreateVolume(&error, ppath, volumeID, aparent); - if (error) { - Log("1 Volser: CreateVolume: Unable to create the volume; aborted, error code %u\n", error); - LogError(error); - DeleteTrans(tt); - return EIO; - } - V_uniquifier(vp) = 1; - V_creationDate(vp) = V_copyDate(vp); - V_inService(vp) = V_blessed(vp) = 1; - V_type(vp) = atype; - AssignVolumeName(&V_disk(vp), aname, 0); - if (doCreateRoot) - ViceCreateRoot(vp); - V_destroyMe(vp) = DESTROY_ME; - V_inService(vp) = 0; - V_maxquota(vp) = 5000; /* set a quota of 5000 at init time */ - VUpdateVolume(&error, vp); - if (error) { - Log("1 Volser: create UpdateVolume failed, code %d\n", error); - LogError(error); - DeleteTrans(tt); - VDetachVolume(&junk, vp); /* rather return the real error code */ - return error; - } - tt->volume = vp; - *atrans = tt->tid; - strcpy(tt->lastProcName, "CreateVolume"); - tt->rxCallPtr = acid; - Log("1 Volser: CreateVolume: volume %u (%s) created\n", volumeID, aname); - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - return 0; -} - -/* delete the volume associated with this transaction */ -afs_int32 -SAFSVolDeleteVolume(struct rx_call *acid, afs_int32 atrans) -{ - afs_int32 code; - - code = VolDeleteVolume(acid, atrans); - osi_auditU(acid, VS_DelVolEvent, code, AUD_LONG, atrans, AUD_END); - return code; -} - -afs_int32 -VolDeleteVolume(struct rx_call *acid, afs_int32 atrans) -{ - register struct volser_trans *tt; - afs_int32 error; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; - tt = FindTrans(atrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: Delete: volume %u already deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - if (DoLogging) - Log("%s is executing Delete Volume %u\n", caller, tt->volid); - strcpy(tt->lastProcName, "DeleteVolume"); - tt->rxCallPtr = acid; - VPurgeVolume(&error, tt->volume); /* don't check error code, it is not set! */ - tt->vflags |= VTDeleted; /* so we know not to do anything else to it */ - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - - Log("1 Volser: Delete: volume %u deleted \n", tt->volid); - return 0; /* vpurgevolume doesn't set an error code */ -} - -/* make a clone of the volume associated with atrans, possibly giving it a new - * number (allocate a new number if *newNumber==0, otherwise use *newNumber - * for the clone's id). The new clone is given the name newName. Finally, due to - * efficiency considerations, if purgeId is non-zero, we purge that volume when doing - * the clone operation. This may be useful when making new backup volumes, for instance - * since the net result of a clone and a purge generally leaves many inode ref counts - * the same, while doing them separately would result in far more iincs and idecs being - * peformed (and they are slow operations). - */ -/* for efficiency reasons, sometimes faster to piggyback a purge here */ -afs_int32 -SAFSVolClone(struct rx_call *acid, afs_int32 atrans, afs_int32 purgeId, - afs_int32 newType, char *newName, afs_int32 *newNumber) -{ - afs_int32 code; - - code = VolClone(acid, atrans, purgeId, newType, newName, newNumber); - osi_auditU(acid, VS_CloneEvent, code, AUD_LONG, atrans, AUD_LONG, purgeId, - AUD_STR, newName, AUD_LONG, newType, AUD_LONG, *newNumber, - AUD_END); - return code; -} - -afs_int32 -VolClone(struct rx_call *acid, afs_int32 atrans, afs_int32 purgeId, - afs_int32 newType, char *newName, afs_int32 *newNumber) -{ - VolumeId newId; - register struct Volume *originalvp, *purgevp, *newvp; - Error error, code; - register struct volser_trans *tt, *ttc; - char caller[MAXKTCNAMELEN]; - - if (strlen(newName) > 31) - return VOLSERBADNAME; - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - if (DoLogging) - Log("%s is executing Clone Volume new name=%s\n", caller, newName); - error = 0; - originalvp = (Volume *) 0; - purgevp = (Volume *) 0; - newvp = (Volume *) 0; - tt = ttc = (struct volser_trans *)0; - - if (!newNumber || !*newNumber) { - Log("1 Volser: Clone: missing volume number for the clone; aborted\n"); - goto fail; - } - newId = *newNumber; - - if (newType != readonlyVolume && newType != backupVolume) - return EINVAL; - tt = FindTrans(atrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: Clone: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - ttc = NewTrans(newId, tt->partition); - if (!ttc) { /* someone is messing with the clone already */ - TRELE(tt); - return VBUSY; - } - strcpy(tt->lastProcName, "Clone"); - tt->rxCallPtr = acid; - - - if (purgeId) { - purgevp = VAttachVolume(&error, purgeId, V_VOLUPD); - if (error) { - Log("1 Volser: Clone: Could not attach 'purge' volume %u; clone aborted\n", purgeId); - goto fail; - } - } else { - purgevp = NULL; - } - originalvp = tt->volume; - if ((V_type(originalvp) == backupVolume) - || (V_type(originalvp) == readonlyVolume)) { - Log("1 Volser: Clone: The volume to be cloned must be a read/write; aborted\n"); - error = EROFS; - goto fail; - } - if ((V_destroyMe(originalvp) == DESTROY_ME) || !V_inService(originalvp)) { - Log("1 Volser: Clone: Volume %d is offline and cannot be cloned\n", - V_id(originalvp)); - error = VOFFLINE; - goto fail; - } - if (purgevp) { - if (originalvp->device != purgevp->device) { - Log("1 Volser: Clone: Volumes %u and %u are on different devices\n", tt->volid, purgeId); - error = EXDEV; - goto fail; - } - if (V_type(purgevp) != readonlyVolume) { - Log("1 Volser: Clone: The \"purge\" volume must be a read only volume; aborted\n"); - error = EINVAL; - goto fail; - } - if (V_type(originalvp) == readonlyVolume - && V_parentId(originalvp) != V_parentId(purgevp)) { - Log("1 Volser: Clone: Volume %u and volume %u were not cloned from the same parent volume; aborted\n", tt->volid, purgeId); - error = EXDEV; - goto fail; - } - if (V_type(originalvp) == readwriteVolume - && tt->volid != V_parentId(purgevp)) { - Log("1 Volser: Clone: Volume %u was not originally cloned from volume %u; aborted\n", purgeId, tt->volid); - error = EXDEV; - goto fail; - } - } - - error = 0; - - newvp = - VCreateVolume(&error, originalvp->partition->name, newId, - V_parentId(originalvp)); - if (error) { - Log("1 Volser: Clone: Couldn't create new volume; clone aborted\n"); - newvp = (Volume *) 0; - goto fail; - } - if (newType == readonlyVolume) - V_cloneId(originalvp) = newId; - Log("1 Volser: Clone: Cloning volume %u to new volume %u\n", tt->volid, - newId); - if (purgevp) - Log("1 Volser: Clone: Purging old read only volume %u\n", purgeId); - CloneVolume(&error, originalvp, newvp, purgevp); - purgevp = NULL; /* clone releases it, maybe even if error */ - if (error) { - Log("1 Volser: Clone: clone operation failed with code %u\n", error); - LogError(error); - goto fail; - } - if (newType == readonlyVolume) { - AssignVolumeName(&V_disk(newvp), V_name(originalvp), ".readonly"); - V_type(newvp) = readonlyVolume; - } else if (newType == backupVolume) { - AssignVolumeName(&V_disk(newvp), V_name(originalvp), ".backup"); - V_type(newvp) = backupVolume; - V_backupId(originalvp) = newId; - } - strcpy(newvp->header->diskstuff.name, newName); - V_creationDate(newvp) = V_copyDate(newvp); - ClearVolumeStats(&V_disk(newvp)); - V_destroyMe(newvp) = DESTROY_ME; - V_inService(newvp) = 0; - if (newType == backupVolume) { - V_backupDate(originalvp) = V_copyDate(newvp); - V_backupDate(newvp) = V_copyDate(newvp); - } - V_inUse(newvp) = 0; - VUpdateVolume(&error, newvp); - if (error) { - Log("1 Volser: Clone: VUpdate failed code %u\n", error); - LogError(error); - goto fail; - } - VDetachVolume(&error, newvp); /* allow file server to get it's hands on it */ - newvp = NULL; - VUpdateVolume(&error, originalvp); - if (error) { - Log("1 Volser: Clone: original update %u\n", error); - LogError(error); - goto fail; - } - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) { - tt = (struct volser_trans *)0; - error = VOLSERTRELE_ERROR; - goto fail; - } - DeleteTrans(ttc); - return 0; - - fail: - if (purgevp) - VDetachVolume(&code, purgevp); - if (newvp) - VDetachVolume(&code, newvp); - if (tt) { - tt->rxCallPtr = (struct rx_call *)0; - TRELE(tt); - } - if (ttc) - DeleteTrans(ttc); - return error; -} - -/* reclone this volume into the specified id */ -afs_int32 -SAFSVolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId) -{ - afs_int32 code; - - code = VolReClone(acid, atrans, cloneId); - osi_auditU(acid, VS_ReCloneEvent, code, AUD_LONG, atrans, AUD_LONG, - cloneId, AUD_END); - return code; -} - -afs_int32 -VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId) -{ - register struct Volume *originalvp, *clonevp; - Error error, code; - afs_int32 newType; - register struct volser_trans *tt, *ttc; - char caller[MAXKTCNAMELEN]; - - /*not a super user */ - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; - if (DoLogging) - Log("%s is executing Reclone Volume %u\n", caller, cloneId); - error = 0; - clonevp = originalvp = (Volume *) 0; - tt = (struct volser_trans *)0; - - tt = FindTrans(atrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolReClone: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - ttc = NewTrans(cloneId, tt->partition); - if (!ttc) { /* someone is messing with the clone already */ - TRELE(tt); - return VBUSY; - } - strcpy(tt->lastProcName, "ReClone"); - tt->rxCallPtr = acid; - - originalvp = tt->volume; - if ((V_type(originalvp) == backupVolume) - || (V_type(originalvp) == readonlyVolume)) { - Log("1 Volser: Clone: The volume to be cloned must be a read/write; aborted\n"); - error = EROFS; - goto fail; - } - if ((V_destroyMe(originalvp) == DESTROY_ME) || !V_inService(originalvp)) { - Log("1 Volser: Clone: Volume %d is offline and cannot be cloned\n", - V_id(originalvp)); - error = VOFFLINE; - goto fail; - } - - clonevp = VAttachVolume(&error, cloneId, V_VOLUPD); - if (error) { - Log("1 Volser: can't attach clone %d\n", cloneId); - goto fail; - } - - newType = V_type(clonevp); /* type of the new volume */ - - if (originalvp->device != clonevp->device) { - Log("1 Volser: Clone: Volumes %u and %u are on different devices\n", - tt->volid, cloneId); - error = EXDEV; - goto fail; - } - if (V_type(clonevp) != readonlyVolume && V_type(clonevp) != backupVolume) { - Log("1 Volser: Clone: The \"recloned\" volume must be a read only volume; aborted\n"); - error = EINVAL; - goto fail; - } - if (V_type(originalvp) == readonlyVolume - && V_parentId(originalvp) != V_parentId(clonevp)) { - Log("1 Volser: Clone: Volume %u and volume %u were not cloned from the same parent volume; aborted\n", tt->volid, cloneId); - error = EXDEV; - goto fail; - } - if (V_type(originalvp) == readwriteVolume - && tt->volid != V_parentId(clonevp)) { - Log("1 Volser: Clone: Volume %u was not originally cloned from volume %u; aborted\n", cloneId, tt->volid); - error = EXDEV; - goto fail; - } - - error = 0; - Log("1 Volser: Clone: Recloning volume %u to volume %u\n", tt->volid, - cloneId); - CloneVolume(&error, originalvp, clonevp, clonevp); - if (error) { - Log("1 Volser: Clone: reclone operation failed with code %d\n", - error); - LogError(error); - goto fail; - } - - /* fix up volume name and type, CloneVolume just propagated RW's */ - if (newType == readonlyVolume) { - AssignVolumeName(&V_disk(clonevp), V_name(originalvp), ".readonly"); - V_type(clonevp) = readonlyVolume; - } else if (newType == backupVolume) { - AssignVolumeName(&V_disk(clonevp), V_name(originalvp), ".backup"); - V_type(clonevp) = backupVolume; - V_backupId(originalvp) = cloneId; - } - /* don't do strcpy onto diskstuff.name, it's still OK from 1st clone */ - - /* pretend recloned volume is a totally new instance */ - V_copyDate(clonevp) = time(0); - V_creationDate(clonevp) = V_copyDate(clonevp); - ClearVolumeStats(&V_disk(clonevp)); - V_destroyMe(clonevp) = 0; - V_inService(clonevp) = 0; - if (newType == backupVolume) { - V_backupDate(originalvp) = V_copyDate(clonevp); - V_backupDate(clonevp) = V_copyDate(clonevp); - } - V_inUse(clonevp) = 0; - VUpdateVolume(&error, clonevp); - if (error) { - Log("1 Volser: Clone: VUpdate failed code %u\n", error); - LogError(error); - goto fail; - } - VDetachVolume(&error, clonevp); /* allow file server to get it's hands on it */ - clonevp = NULL; - VUpdateVolume(&error, originalvp); - if (error) { - Log("1 Volser: Clone: original update %u\n", error); - LogError(error); - goto fail; - } - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) { - tt = (struct volser_trans *)0; - error = VOLSERTRELE_ERROR; - goto fail; - } - - DeleteTrans(ttc); - - { - struct DiskPartition *tpartp = originalvp->partition; - FSYNC_askfs(cloneId, tpartp->name, FSYNC_RESTOREVOLUME, 0); - } - return 0; - - fail: - if (clonevp) - VDetachVolume(&code, clonevp); - if (tt) { - tt->rxCallPtr = (struct rx_call *)0; - TRELE(tt); - } - if (ttc) - DeleteTrans(ttc); - return error; -} - -/* create a new transaction, associated with volume and partition. Type of - * volume transaction is spec'd by iflags. New trans id is returned in ttid. - * See volser.h for definition of iflags (the constants are named IT*). - */ -afs_int32 -SAFSVolTransCreate(struct rx_call *acid, afs_int32 volume, afs_int32 partition, - afs_int32 iflags, afs_int32 *ttid) -{ - afs_int32 code; - - code = VolTransCreate(acid, volume, partition, iflags, ttid); - osi_auditU(acid, VS_TransCrEvent, code, AUD_LONG, *ttid, AUD_LONG, volume, - AUD_END); - return code; -} - -afs_int32 -VolTransCreate(struct rx_call *acid, afs_int32 volume, afs_int32 partition, - afs_int32 iflags, afs_int32 *ttid) -{ - register struct volser_trans *tt; - register Volume *tv; - afs_int32 error, code; - afs_int32 mode; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - if (iflags & ITCreate) - mode = V_SECRETLY; - else if (iflags & ITBusy) - mode = V_CLONE; - else if (iflags & ITReadOnly) - mode = V_READONLY; - else if (iflags & ITOffline) - mode = V_VOLUPD; - else { - Log("1 Volser: TransCreate: Could not create trans, error %u\n", - EINVAL); - LogError(EINVAL); - return EINVAL; - } - tt = NewTrans(volume, partition); - if (!tt) { - /* can't create a transaction? put the volume back */ - Log("1 transcreate: can't create transaction\n"); - return VOLSERVOLBUSY; - } - tv = XAttachVolume(&error, volume, partition, mode); - if (error) { - /* give up */ - if (tv) - VDetachVolume(&code, tv); - DeleteTrans(tt); - return error; - } - tt->volume = tv; - *ttid = tt->tid; - tt->iflags = iflags; - tt->vflags = 0; - strcpy(tt->lastProcName, "TransCreate"); - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - - return 0; -} - -/* using aindex as a 0-based index, return the aindex'th volume on this server - * Both the volume number and partition number (one-based) are returned. - */ -afs_int32 -SAFSVolGetNthVolume(struct rx_call *acid, afs_int32 aindex, afs_int32 *avolume, - afs_int32 *apart) -{ - afs_int32 code; - - code = VolGetNthVolume(acid, aindex, avolume, apart); - osi_auditU(acid, VS_GetNVolEvent, code, AUD_LONG, *avolume, AUD_END); - return code; -} - -afs_int32 -VolGetNthVolume(struct rx_call *acid, afs_int32 aindex, afs_int32 *avolume, - afs_int32 *apart) -{ - Log("1 Volser: GetNthVolume: Not yet implemented\n"); - return VOLSERNO_OP; -} - -/* return the volume flags (VT* constants in volser.h) associated with this - * transaction. - */ -afs_int32 -SAFSVolGetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 *aflags) -{ - afs_int32 code; - - code = VolGetFlags(acid, atid, aflags); - osi_auditU(acid, VS_GetFlgsEvent, code, AUD_LONG, atid, AUD_END); - return code; -} - -afs_int32 -VolGetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 *aflags) -{ - register struct volser_trans *tt; - - tt = FindTrans(atid); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolGetFlags: volume %u has been deleted \n", - tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "GetFlags"); - tt->rxCallPtr = acid; - *aflags = tt->vflags; - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - - return 0; -} - -/* Change the volume flags (VT* constants in volser.h) associated with this - * transaction. Effects take place immediately on volume, although volume - * remains attached as usual by the transaction. - */ -afs_int32 -SAFSVolSetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 aflags) -{ - afs_int32 code; - - code = VolSetFlags(acid, atid, aflags); - osi_auditU(acid, VS_SetFlgsEvent, code, AUD_LONG, atid, AUD_LONG, aflags, - AUD_END); - return code; -} - -afs_int32 -VolSetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 aflags) -{ - register struct volser_trans *tt; - register struct Volume *vp; - afs_int32 error; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - /* find the trans */ - tt = FindTrans(atid); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolSetFlags: volume %u has been deleted \n", - tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "SetFlags"); - tt->rxCallPtr = acid; - vp = tt->volume; /* pull volume out of transaction */ - - /* check if we're allowed to make any updates */ - if (tt->iflags & ITReadOnly) { - TRELE(tt); - return EROFS; - } - - /* handle delete-on-salvage flag */ - if (aflags & VTDeleteOnSalvage) { - V_destroyMe(tt->volume) = DESTROY_ME; - } else { - V_destroyMe(tt->volume) = 0; - } - - if (aflags & VTOutOfService) { - V_inService(vp) = 0; - } else { - V_inService(vp) = 1; - } - VUpdateVolume(&error, vp); - tt->vflags = aflags; - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt) && !error) - return VOLSERTRELE_ERROR; - - return error; -} - -/* dumpS the volume associated with a particular transaction from a particular - * date. Send the dump to a different transaction (destTrans) on the server - * specified by the destServer structure. - */ -afs_int32 -SAFSVolForward(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, - struct destServer *destination, afs_int32 destTrans, - struct restoreCookie *cookie) -{ - afs_int32 code; - - code = - VolForward(acid, fromTrans, fromDate, destination, destTrans, cookie); - osi_auditU(acid, VS_ForwardEvent, code, AUD_LONG, fromTrans, AUD_HOST, - destination->destHost, AUD_LONG, destTrans, AUD_END); - return code; -} - -afs_int32 -VolForward(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, - struct destServer *destination, afs_int32 destTrans, - struct restoreCookie *cookie) -{ - register struct volser_trans *tt; - register afs_int32 code; - register struct rx_connection *tcon; - struct rx_call *tcall; - register struct Volume *vp; - struct rx_securityClass *securityObject; - afs_int32 securityIndex; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - /* initialize things */ - tcon = (struct rx_connection *)0; - tt = (struct volser_trans *)0; - - /* find the local transaction */ - tt = FindTrans(fromTrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolForward: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - vp = tt->volume; - strcpy(tt->lastProcName, "Forward"); - - /* get auth info for the this connection (uses afs from ticket file) */ - code = afsconf_ClientAuth(tdir, &securityObject, &securityIndex); - if (code) { - TRELE(tt); - return code; - } - - /* make an rpc connection to the other server */ - tcon = - rx_NewConnection(htonl(destination->destHost), - htons(destination->destPort), VOLSERVICE_ID, - securityObject, securityIndex); - if (!tcon) { - tt->rxCallPtr = (struct rx_call *)0; - TRELE(tt); - return ENOTCONN; - } - tcall = rx_NewCall(tcon); - tt->rxCallPtr = tcall; - /* start restore going. fromdate == 0 --> doing an incremental dump/restore */ - code = StartAFSVolRestore(tcall, destTrans, (fromDate ? 1 : 0), cookie); - if (code) { - goto fail; - } - - /* these next calls implictly call rx_Write when writing out data */ - code = DumpVolume(tcall, vp, fromDate, 0); /* last field = don't dump all dirs */ - if (code) - goto fail; - EndAFSVolRestore(tcall); /* probably doesn't do much */ - tt->rxCallPtr = (struct rx_call *)0; - code = rx_EndCall(tcall, 0); - rx_DestroyConnection(tcon); /* done with the connection */ - tcon = NULL; - if (code) - goto fail; - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - - return 0; - - fail: - if (tcon) { - (void)rx_EndCall(tcall, 0); - rx_DestroyConnection(tcon); - } - if (tt) { - tt->rxCallPtr = (struct rx_call *)0; - TRELE(tt); - } - return code; -} - -/* Start a dump and send it to multiple places simultaneously. - * If this returns an error (eg, return ENOENT), it means that - * none of the releases worked. If this returns 0, that means - * that one or more of the releases worked, and the caller has - * to examine the results array to see which one(s). - * This will only do EITHER incremental or full, not both, so it's - * the caller's responsibility to be sure that all the destinations - * need just an incremental (and from the same time), if that's - * what we're doing. - */ -afs_int32 -SAFSVolForwardMultiple(struct rx_call *acid, afs_int32 fromTrans, afs_int32 - fromDate, manyDests *destinations, afs_int32 spare, - struct restoreCookie *cookie, manyResults *results) -{ - afs_int32 securityIndex; - struct rx_securityClass *securityObject; - char caller[MAXKTCNAMELEN]; - struct volser_trans *tt; - afs_int32 ec, code, *codes; - struct rx_connection **tcons; - struct rx_call **tcalls; - struct Volume *vp; - int i, is_incremental; - - if (results) - memset(results, 0, sizeof(manyResults)); - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - tt = FindTrans(fromTrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolForward: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - vp = tt->volume; - strcpy(tt->lastProcName, "ForwardMulti"); - - /* (fromDate == 0) ==> incremental dump */ - is_incremental = (fromDate ? 1 : 0); - - i = results->manyResults_len = destinations->manyDests_len; - results->manyResults_val = codes = - (afs_int32 *) malloc(i * sizeof(afs_int32)); - tcons = - (struct rx_connection **)malloc(i * sizeof(struct rx_connection *)); - tcalls = (struct rx_call **)malloc(i * sizeof(struct rx_call *)); - - /* get auth info for this connection (uses afs from ticket file) */ - code = afsconf_ClientAuth(tdir, &securityObject, &securityIndex); - if (code) { - goto fail; /* in order to audit each failure */ - } - - /* make connections to all the other servers */ - for (i = 0; i < destinations->manyDests_len; i++) { - struct replica *dest = &(destinations->manyDests_val[i]); - tcons[i] = - rx_NewConnection(htonl(dest->server.destHost), - htons(dest->server.destPort), VOLSERVICE_ID, - securityObject, securityIndex); - if (!tcons[i]) { - codes[i] = ENOTCONN; - } else { - if (!(tcalls[i] = rx_NewCall(tcons[i]))) - codes[i] = ENOTCONN; - else { - codes[i] = - StartAFSVolRestore(tcalls[i], dest->trans, is_incremental, - cookie); - if (codes[i]) { - (void)rx_EndCall(tcalls[i], 0); - tcalls[i] = 0; - rx_DestroyConnection(tcons[i]); - tcons[i] = 0; - } - } - } - } - - /* these next calls implictly call rx_Write when writing out data */ - code = DumpVolMulti(tcalls, i, vp, fromDate, 0, codes); - - - fail: - for (i--; i >= 0; i--) { - struct replica *dest = &(destinations->manyDests_val[i]); - - if (!code && tcalls[i] && !codes[i]) { - EndAFSVolRestore(tcalls[i]); - } - if (tcalls[i]) { - ec = rx_EndCall(tcalls[i], 0); - if (!codes[i]) - codes[i] = ec; - } - if (tcons[i]) { - rx_DestroyConnection(tcons[i]); /* done with the connection */ - } - - osi_auditU(acid, VS_ForwardEvent, (code ? code : codes[i]), AUD_LONG, - fromTrans, AUD_HOST, dest->server.destHost, AUD_LONG, - dest->trans, AUD_END); - } - free(tcons); - free(tcalls); - - if (tt) { - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt) && !code) /* return the first code if it's set */ - return VOLSERTRELE_ERROR; - } - - return code; -} - -afs_int32 -SAFSVolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate) -{ - afs_int32 code; - - code = VolDump(acid, fromTrans, fromDate); - osi_auditU(acid, VS_DumpEvent, code, AUD_LONG, fromTrans, AUD_END); - return code; -} - -afs_int32 -VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate) -{ - int code = 0; - register struct volser_trans *tt; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - tt = FindTrans(fromTrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolDump: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "Dump"); - tt->rxCallPtr = acid; - code = DumpVolume(acid, tt->volume, fromDate, 1); /* squirt out the volume's data, too */ - if (code) { - tt->rxCallPtr = (struct rx_call *)0; - TRELE(tt); - return code; - } - tt->rxCallPtr = (struct rx_call *)0; - - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - - return 0; -} - -/* - * Ha! No more helper process! - */ -afs_int32 -SAFSVolRestore(struct rx_call *acid, afs_int32 atrans, afs_int32 aflags, - struct restoreCookie *cookie) -{ - afs_int32 code; - - code = VolRestore(acid, atrans, aflags, cookie); - osi_auditU(acid, VS_RestoreEvent, code, AUD_LONG, atrans, AUD_END); - return code; -} - -afs_int32 -VolRestore(struct rx_call *acid, afs_int32 atrans, afs_int32 aflags, - struct restoreCookie *cookie) -{ - register struct volser_trans *tt; - register afs_int32 code, tcode; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - tt = FindTrans(atrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolRestore: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "Restore"); - tt->rxCallPtr = acid; - - DFlushVolume(V_parentId(tt->volume)); /* Ensure dir buffers get dropped */ - - code = RestoreVolume(acid, tt->volume, (aflags & 1), cookie); /* last is incrementalp */ - FSYNC_askfs(tt->volid, NULL, FSYNC_RESTOREVOLUME, 0l); /*break call backs on the - * restored volume */ - tt->rxCallPtr = (struct rx_call *)0; - tcode = TRELE(tt); - - return (code ? code : tcode); -} - -/* end a transaction, returning the transaction's final error code in rcode */ -afs_int32 -SAFSVolEndTrans(struct rx_call *acid, afs_int32 destTrans, afs_int32 *rcode) -{ - afs_int32 code; - - code = VolEndTrans(acid, destTrans, rcode); - osi_auditU(acid, VS_EndTrnEvent, code, AUD_LONG, destTrans, AUD_END); - return code; -} - -afs_int32 -VolEndTrans(struct rx_call *acid, afs_int32 destTrans, afs_int32 *rcode) -{ - register struct volser_trans *tt; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - tt = FindTrans(destTrans); - if (!tt) { - return ENOENT; - } - *rcode = tt->returnCode; - DeleteTrans(tt); /* this does an implicit TRELE */ - - return 0; -} - -afs_int32 -SAFSVolSetForwarding(struct rx_call *acid, afs_int32 atid, afs_int32 anewsite) -{ - afs_int32 code; - - code = VolSetForwarding(acid, atid, anewsite); - osi_auditU(acid, VS_SetForwEvent, code, AUD_LONG, atid, AUD_HOST, - anewsite, AUD_END); - return code; -} - -afs_int32 -VolSetForwarding(struct rx_call *acid, afs_int32 atid, afs_int32 anewsite) -{ - register struct volser_trans *tt; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - tt = FindTrans(atid); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolSetForwarding: volume %u has been deleted \n", - tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "SetForwarding"); - tt->rxCallPtr = acid; - FSYNC_askfs(tt->volid, NULL, FSYNC_MOVEVOLUME, anewsite); - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - - return 0; -} - -afs_int32 -SAFSVolGetStatus(struct rx_call *acid, afs_int32 atrans, - register struct volser_status *astatus) -{ - afs_int32 code; - - code = VolGetStatus(acid, atrans, astatus); - osi_auditU(acid, VS_GetStatEvent, code, AUD_LONG, atrans, AUD_END); - return code; -} - -afs_int32 -VolGetStatus(struct rx_call *acid, afs_int32 atrans, - register struct volser_status *astatus) -{ - register struct Volume *tv; - register struct VolumeDiskData *td; - struct volser_trans *tt; - - - tt = FindTrans(atrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolGetStatus: volume %u has been deleted \n", - tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "GetStatus"); - tt->rxCallPtr = acid; - tv = tt->volume; - if (!tv) { - tt->rxCallPtr = (struct rx_call *)0; - TRELE(tt); - return ENOENT; - } - - td = &tv->header->diskstuff; - astatus->volID = td->id; - astatus->nextUnique = td->uniquifier; - astatus->type = td->type; - astatus->parentID = td->parentId; - astatus->cloneID = td->cloneId; - astatus->backupID = td->backupId; - astatus->restoredFromID = td->restoredFromId; - astatus->maxQuota = td->maxquota; - astatus->minQuota = td->minquota; - astatus->owner = td->owner; - astatus->creationDate = td->creationDate; - astatus->accessDate = td->accessDate; - astatus->updateDate = td->updateDate; - astatus->expirationDate = td->expirationDate; - astatus->backupDate = td->backupDate; - astatus->copyDate = td->copyDate; - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - - return 0; -} - -afs_int32 -SAFSVolSetInfo(struct rx_call *acid, afs_int32 atrans, - register struct volintInfo *astatus) -{ - afs_int32 code; - - code = VolSetInfo(acid, atrans, astatus); - osi_auditU(acid, VS_SetInfoEvent, code, AUD_LONG, atrans, AUD_END); - return code; -} - -afs_int32 -VolSetInfo(struct rx_call *acid, afs_int32 atrans, - register struct volintInfo *astatus) -{ - register struct Volume *tv; - register struct VolumeDiskData *td; - struct volser_trans *tt; - char caller[MAXKTCNAMELEN]; - afs_int32 error; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - tt = FindTrans(atrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolSetInfo: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "SetStatus"); - tt->rxCallPtr = acid; - tv = tt->volume; - if (!tv) { - tt->rxCallPtr = (struct rx_call *)0; - TRELE(tt); - return ENOENT; - } - - td = &tv->header->diskstuff; - /* - * Add more fields as necessary - */ - if (astatus->maxquota != -1) - td->maxquota = astatus->maxquota; - if (astatus->dayUse != -1) - td->dayUse = astatus->dayUse; - VUpdateVolume(&error, tv); - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - return 0; -} - - -afs_int32 -SAFSVolGetName(struct rx_call *acid, afs_int32 atrans, char **aname) -{ - afs_int32 code; - - code = VolGetName(acid, atrans, aname); - osi_auditU(acid, VS_GetNameEvent, code, AUD_LONG, atrans, AUD_END); - return code; -} - -afs_int32 -VolGetName(struct rx_call *acid, afs_int32 atrans, char **aname) -{ - register struct Volume *tv; - register struct VolumeDiskData *td; - struct volser_trans *tt; - register int len; - - *aname = NULL; - tt = FindTrans(atrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolGetName: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "GetName"); - tt->rxCallPtr = acid; - tv = tt->volume; - if (!tv) { - tt->rxCallPtr = (struct rx_call *)0; - TRELE(tt); - return ENOENT; - } - - td = &tv->header->diskstuff; - len = strlen(td->name) + 1; /* don't forget the null */ - if (len >= SIZE) { - tt->rxCallPtr = (struct rx_call *)0; - TRELE(tt); - return E2BIG; - } - *aname = (char *)malloc(len); - strcpy(*aname, td->name); - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - - return 0; -} - -/*this is a handshake to indicate that the next call will be SAFSVolRestore - * - a noop now !*/ -afs_int32 -SAFSVolSignalRestore(struct rx_call *acid, char volname[], int volType, - afs_int32 parentId, afs_int32 cloneId) -{ - return 0; -} - - -/*return a list of all partitions on the server. The non mounted - *partitions are returned as -1 in the corresponding slot in partIds*/ -afs_int32 -SAFSVolListPartitions(struct rx_call *acid, struct pIDs *partIds) -{ - afs_int32 code; - - code = VolListPartitions(acid, partIds); - osi_auditU(acid, VS_ListParEvent, code, AUD_END); - return code; -} - -afs_int32 -VolListPartitions(struct rx_call *acid, struct pIDs *partIds) -{ - char namehead[9]; - char i; - - strcpy(namehead, "/vicep"); /*7 including null terminator */ - - /* Just return attached partitions. */ - namehead[7] = '\0'; - for (i = 0; i < 26; i++) { - namehead[6] = i + 'a'; - if (VGetPartition(namehead, 0)) - partIds->partIds[i] = VGetPartition(namehead, 0) ? i : -1; - } - - return 0; -} - -/*return a list of all partitions on the server. The non mounted - *partitions are returned as -1 in the corresponding slot in partIds*/ -afs_int32 -SAFSVolXListPartitions(struct rx_call *acid, struct partEntries *pEntries) -{ - afs_int32 code; - - code = XVolListPartitions(acid, pEntries); - osi_auditU(acid, VS_ListParEvent, code, AUD_END); - return code; -} - -afs_int32 -XVolListPartitions(struct rx_call *acid, struct partEntries *pEntries) -{ - struct stat rbuf, pbuf; - char namehead[9]; - struct partList partList; - struct DiskPartition *dp; - int i, j = 0, k; - - strcpy(namehead, "/vicep"); /*7 including null terminator */ - - /* Only report attached partitions */ - for (i = 0; i < VOLMAXPARTS; i++) { - if (i < 26) { - namehead[6] = i + 'a'; - namehead[7] = '\0'; - } else { - k = i - 26; - namehead[6] = 'a' + (k / 26); - namehead[7] = 'a' + (k % 26); - namehead[8] = '\0'; - } - dp = VGetPartition(namehead, 0); - if (dp) - partList.partId[j++] = i; - } - pEntries->partEntries_val = (afs_int32 *) malloc(j * sizeof(int)); - memcpy((char *)pEntries->partEntries_val, (char *)&partList, - j * sizeof(int)); - pEntries->partEntries_len = j; - return 0; - -} - -/*extract the volume id from string vname. Its of the form " V0*.vol "*/ -afs_int32 -ExtractVolId(char vname[]) -{ - int i; - char name[VOLSER_MAXVOLNAME + 1]; - - strcpy(name, vname); - i = 0; - while (name[i] == 'V' || name[i] == '0') - i++; - - name[11] = '\0'; /* smash the "." */ - return (atol(&name[i])); -} - -/*return the name of the next volume header in the directory associated with dirp and dp. -*the volume id is returned in volid, and volume header name is returned in volname*/ -int -GetNextVol(DIR * dirp, char *volname, afs_int32 * volid) -{ - struct dirent *dp; - - dp = readdir(dirp); /*read next entry in the directory */ - if (dp) { - if ((dp->d_name[0] == 'V') && !strcmp(&(dp->d_name[11]), VHDREXT)) { - *volid = ExtractVolId(dp->d_name); - strcpy(volname, dp->d_name); - return 0; /*return the name of the file representing a volume */ - } else { - strcpy(volname, ""); - return 0; /*volname doesnot represent a volume */ - } - } else { - strcpy(volname, "EOD"); - return 0; /*end of directory */ - } - -} - -/*return the header information about the */ -afs_int32 -SAFSVolListOneVolume(struct rx_call *acid, afs_int32 partid, afs_int32 - volumeId, volEntries *volumeInfo) -{ - afs_int32 code; - - code = VolListOneVolume(acid, partid, volumeId, volumeInfo); - osi_auditU(acid, VS_Lst1VolEvent, code, AUD_LONG, volumeId, AUD_END); - return code; -} - -afs_int32 -VolListOneVolume(struct rx_call *acid, afs_int32 partid, afs_int32 - volumeId, volEntries *volumeInfo) -{ - volintInfo *pntr; - register struct Volume *tv; - struct DiskPartition *partP; - struct volser_trans *ttc; - char pname[9], volname[20]; - afs_int32 error = 0; - DIR *dirp; - afs_int32 volid; - int found = 0; - unsigned int now; - - volumeInfo->volEntries_val = (volintInfo *) malloc(sizeof(volintInfo)); - pntr = volumeInfo->volEntries_val; - volumeInfo->volEntries_len = 1; - if (GetPartName(partid, pname)) - return VOLSERILLEGAL_PARTITION; - if (!(partP = VGetPartition(pname, 0))) - return VOLSERILLEGAL_PARTITION; - dirp = opendir(VPartitionPath(partP)); - if (dirp == NULL) - return VOLSERILLEGAL_PARTITION; - strcpy(volname, ""); - ttc = (struct volser_trans *)0; - tv = (Volume *) 0; /* volume not attached */ - - while (strcmp(volname, "EOD") && !found) { /*while there are more volumes in the partition */ - - if (!strcmp(volname, "")) { /* its not a volume, fetch next file */ - GetNextVol(dirp, volname, &volid); - continue; /*back to while loop */ - } - - if (volid == volumeId) { /*copy other things too */ - found = 1; -#ifndef AFS_PTHREAD_ENV - IOMGR_Poll(); /*make sure that the client doesnot time out */ -#endif - ttc = NewTrans(volid, partid); - if (!ttc) { - pntr->status = VBUSY; - pntr->volid = volid; - goto drop; - } - tv = VAttachVolumeByName(&error, pname, volname, V_READONLY); - if (error) { - pntr->status = 0; /*things are messed up */ - strcpy(pntr->name, volname); - pntr->volid = volid; - Log("1 Volser: ListVolumes: Could not attach volume %u (%s:%s), error=%d\n", volid, pname, volname, error); - goto drop; - } - if (tv->header->diskstuff.destroyMe == DESTROY_ME) { - /*this volume will be salvaged */ - pntr->status = 0; - strcpy(pntr->name, volname); - pntr->volid = volid; - Log("1 Volser: ListVolumes: Volume %u (%s) will be destroyed on next salvage\n", volid, volname); - goto drop; - } - - if (tv->header->diskstuff.needsSalvaged) { - /*this volume will be salvaged */ - pntr->status = 0; - strcpy(pntr->name, volname); - pntr->volid = volid; - Log("1 Volser: ListVolumes: Volume %u (%s) needs to be salvaged\n", volid, volname); - goto drop; - } - - /*read in the relevant info */ - pntr->status = VOK; /*its ok */ - pntr->volid = tv->header->diskstuff.id; - strcpy(pntr->name, tv->header->diskstuff.name); - pntr->type = tv->header->diskstuff.type; /*if ro volume */ - pntr->cloneID = tv->header->diskstuff.cloneId; /*if rw volume */ - pntr->backupID = tv->header->diskstuff.backupId; - pntr->parentID = tv->header->diskstuff.parentId; - pntr->copyDate = tv->header->diskstuff.copyDate; - pntr->inUse = tv->header->diskstuff.inUse; - pntr->size = tv->header->diskstuff.diskused; - pntr->needsSalvaged = tv->header->diskstuff.needsSalvaged; - pntr->destroyMe = tv->header->diskstuff.destroyMe; - pntr->maxquota = tv->header->diskstuff.maxquota; - pntr->filecount = tv->header->diskstuff.filecount; - now = FT_ApproxTime(); - if (now - tv->header->diskstuff.dayUseDate > OneDay) - pntr->dayUse = 0; - else - pntr->dayUse = tv->header->diskstuff.dayUse; - pntr->creationDate = tv->header->diskstuff.creationDate; - pntr->accessDate = tv->header->diskstuff.accessDate; - pntr->updateDate = tv->header->diskstuff.updateDate; - pntr->backupDate = tv->header->diskstuff.backupDate; - pntr->spare0 = tv->header->diskstuff.minquota; - pntr->spare1 = - (long)tv->header->diskstuff.weekUse[0] + - (long)tv->header->diskstuff.weekUse[1] + - (long)tv->header->diskstuff.weekUse[2] + - (long)tv->header->diskstuff.weekUse[3] + - (long)tv->header->diskstuff.weekUse[4] + - (long)tv->header->diskstuff.weekUse[5] + - (long)tv->header->diskstuff.weekUse[6]; - pntr->flags = pntr->spare2 = pntr->spare3 = (long)0; - VDetachVolume(&error, tv); /*free the volume */ - tv = (Volume *) 0; - if (error) { - pntr->status = 0; /*things are messed up */ - strcpy(pntr->name, volname); - Log("1 Volser: ListVolumes: Could not detach volume %s\n", - volname); - goto drop; - } - } - GetNextVol(dirp, volname, &volid); - } - drop: - if (tv) { - VDetachVolume(&error, tv); - tv = (Volume *) 0; - } - if (ttc) { - DeleteTrans(ttc); - ttc = (struct volser_trans *)0; - } - - closedir(dirp); - if (found) - return 0; - else - return ENODEV; -} - -/*------------------------------------------------------------------------ - * EXPORTED SAFSVolXListOneVolume - * - * Description: - * Returns extended info on volume a_volID on partition a_partID. - * - * Arguments: - * a_rxCidP : Pointer to the Rx call we're performing. - * a_partID : Partition for which we want the extended list. - * a_volID : Volume ID we wish to know about. - * a_volumeXInfoP : Ptr to the extended info blob. - * - * Returns: - * 0 Successful operation - * VOLSERILLEGAL_PARTITION if we got a bogus partition ID - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -afs_int32 -SAFSVolXListOneVolume(struct rx_call *a_rxCidP, afs_int32 a_partID, - afs_int32 a_volID, volXEntries *a_volumeXInfoP) -{ - afs_int32 code; - - code = VolXListOneVolume(a_rxCidP, a_partID, a_volID, a_volumeXInfoP); - osi_auditU(a_rxCidP, VS_XLst1VlEvent, code, AUD_LONG, a_volID, AUD_END); - return code; -} - -afs_int32 -VolXListOneVolume(struct rx_call *a_rxCidP, afs_int32 a_partID, - afs_int32 a_volID, volXEntries *a_volumeXInfoP) -{ /*SAFSVolXListOneVolume */ - - volintXInfo *xInfoP; /*Ptr to the extended vol info */ - register struct Volume *tv; /*Volume ptr */ - struct volser_trans *ttc; /*Volume transaction ptr */ - struct DiskPartition *partP; /*Ptr to partition */ - char pname[9], volname[20]; /*Partition, volume names */ - afs_int32 error; /*Error code */ - afs_int32 code; /*Return code */ - DIR *dirp; /*Partition directory ptr */ - afs_int32 currVolID; /*Current volume ID */ - int found = 0; /*Did we find the volume we need? */ - struct VolumeDiskData *volDiskDataP; /*Ptr to on-disk volume data */ - int numStatBytes; /*Num stat bytes to copy per volume */ - unsigned int now; - - /* - * Set up our pointers for action, marking our structure to hold exactly - * one entry. Also, assume we'll fail in our quest. - */ - a_volumeXInfoP->volXEntries_val = - (volintXInfo *) malloc(sizeof(volintXInfo)); - xInfoP = a_volumeXInfoP->volXEntries_val; - a_volumeXInfoP->volXEntries_len = 1; - code = ENODEV; - - /* - * If the partition name we've been given is bad, bogue out. - */ - if (GetPartName(a_partID, pname)) - return (VOLSERILLEGAL_PARTITION); - - /* - * Open the directory representing the given AFS parttion. If we can't - * do that, we lose. - */ - if (!(partP = VGetPartition(pname, 0))) - return VOLSERILLEGAL_PARTITION; - dirp = opendir(VPartitionPath(partP)); - if (dirp == NULL) - return (VOLSERILLEGAL_PARTITION); - - /* - * Sweep through the partition directory, looking for the desired entry. - * First, of course, figure out how many stat bytes to copy out of each - * volume. - */ - numStatBytes = - 4 * ((2 * VOLINT_STATS_NUM_RWINFO_FIELDS) + - (4 * VOLINT_STATS_NUM_TIME_FIELDS)); - strcpy(volname, ""); - ttc = (struct volser_trans *)0; /*No transaction yet */ - tv = (Volume *) 0; /*Volume not yet attached */ - - while (strcmp(volname, "EOD") && !found) { - /* - * If this is not a volume, move on to the next entry in the - * partition's directory. - */ - if (!strcmp(volname, "")) { - GetNextVol(dirp, volname, &currVolID); - continue; - } - - if (currVolID == a_volID) { - /* - * We found the volume entry we're interested. Pull out the - * extended information, remembering to poll (so that the client - * doesn't time out) and to set up a transaction on the volume. - */ - found = 1; -#ifndef AFS_PTHREAD_ENV - IOMGR_Poll(); -#endif - ttc = NewTrans(currVolID, a_partID); - if (!ttc) { - /* - * Couldn't get a transaction on this volume; let our caller - * know it's busy. - */ - xInfoP->status = VBUSY; - xInfoP->volid = currVolID; - goto drop; - } - - /* - * Attach the volume, give up on the volume if we can't. - */ - tv = VAttachVolumeByName(&error, pname, volname, V_READONLY); - if (error) { - xInfoP->status = 0; /*things are messed up */ - strcpy(xInfoP->name, volname); - xInfoP->volid = currVolID; - Log("1 Volser: XListOneVolume: Could not attach volume %u\n", - currVolID); - goto drop; - } - - /* - * Also bag out on this volume if it's been marked as needing a - * salvage or to-be-destroyed. - */ - volDiskDataP = &(tv->header->diskstuff); - if (volDiskDataP->destroyMe == DESTROY_ME) { - xInfoP->status = 0; - strcpy(xInfoP->name, volname); - xInfoP->volid = currVolID; - Log("1 Volser: XListOneVolume: Volume %u will be destroyed on next salvage\n", currVolID); - goto drop; - } - - if (volDiskDataP->needsSalvaged) { - xInfoP->status = 0; - strcpy(xInfoP->name, volname); - xInfoP->volid = currVolID; - Log("1 Volser: XListOneVolume: Volume %u needs to be salvaged\n", currVolID); - goto drop; - } - - /* - * Pull out the desired info and stuff it into the area we'll be - * returning to our caller. - */ - strcpy(xInfoP->name, volDiskDataP->name); - xInfoP->volid = volDiskDataP->id; - xInfoP->type = volDiskDataP->type; - xInfoP->backupID = volDiskDataP->backupId; - xInfoP->parentID = volDiskDataP->parentId; - xInfoP->cloneID = volDiskDataP->cloneId; - xInfoP->status = VOK; - xInfoP->copyDate = volDiskDataP->copyDate; - xInfoP->inUse = volDiskDataP->inUse; - xInfoP->creationDate = volDiskDataP->creationDate; - xInfoP->accessDate = volDiskDataP->accessDate; - xInfoP->updateDate = volDiskDataP->updateDate; - xInfoP->backupDate = volDiskDataP->backupDate; - now = FT_ApproxTime(); - if (now - volDiskDataP->dayUseDate > OneDay) - xInfoP->dayUse = 0; - else - xInfoP->dayUse = volDiskDataP->dayUse; - xInfoP->filecount = volDiskDataP->filecount; - xInfoP->maxquota = volDiskDataP->maxquota; - xInfoP->size = volDiskDataP->diskused; - - /* - * Copy out the stat fields in a single operation. - */ - memcpy((char *)&(xInfoP->stat_reads[0]), - (char *)&(volDiskDataP->stat_reads[0]), numStatBytes); - - /* - * We're done copying. Detach the volume and iterate (at this - * point, since we found our volume, we'll then drop out of the - * loop). - */ - VDetachVolume(&error, tv); - tv = (Volume *) 0; - if (error) { - xInfoP->status = 0; - strcpy(xInfoP->name, volname); - Log("1 Volser: XListOneVolumes Couldn't detach volume %s\n", - volname); - goto drop; - } - - /* - * At this point, we're golden. - */ - code = 0; - } /*Found desired volume */ - GetNextVol(dirp, volname, &currVolID); - } - - /* - * Drop the transaction we have for this volume. - */ - drop: - if (tv) { - VDetachVolume(&error, tv); - tv = (Volume *) 0; - } - if (ttc) { - DeleteTrans(ttc); - ttc = (struct volser_trans *)0; - } - - /* - * Clean up before going to dinner: close the partition directory, - * return the proper value. - */ - closedir(dirp); - return (code); - -} /*SAFSVolXListOneVolume */ - -/*returns all the volumes on partition partid. If flags = 1 then all the -* relevant info about the volumes is also returned */ -afs_int32 -SAFSVolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags, - volEntries *volumeInfo) -{ - afs_int32 code; - - code = VolListVolumes(acid, partid, flags, volumeInfo); - osi_auditU(acid, VS_ListVolEvent, code, AUD_END); - return code; -} - -afs_int32 -VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags, - volEntries *volumeInfo) -{ - volintInfo *pntr; - register struct Volume *tv; - struct DiskPartition *partP; - struct volser_trans *ttc; - afs_int32 allocSize = 1000; /*to be changed to a larger figure */ - char pname[9], volname[20]; - afs_int32 error = 0; - DIR *dirp; - afs_int32 volid; - unsigned int now; - - volumeInfo->volEntries_val = - (volintInfo *) malloc(allocSize * sizeof(volintInfo)); - pntr = volumeInfo->volEntries_val; - volumeInfo->volEntries_len = 0; - if (GetPartName(partid, pname)) - return VOLSERILLEGAL_PARTITION; - if (!(partP = VGetPartition(pname, 0))) - return VOLSERILLEGAL_PARTITION; - dirp = opendir(VPartitionPath(partP)); - if (dirp == NULL) - return VOLSERILLEGAL_PARTITION; - strcpy(volname, ""); - while (strcmp(volname, "EOD")) { /*while there are more partitions in the partition */ - ttc = (struct volser_trans *)0; /* new one for each pass */ - tv = (Volume *) 0; /* volume not attached */ - - if (!strcmp(volname, "")) { /* its not a volume, fetch next file */ - GetNextVol(dirp, volname, &volid); - continue; /*back to while loop */ - } - - if (flags) { /*copy other things too */ -#ifndef AFS_PTHREAD_ENV - IOMGR_Poll(); /*make sure that the client doesnot time out */ -#endif - ttc = NewTrans(volid, partid); - if (!ttc) { - pntr->status = VBUSY; - pntr->volid = volid; - goto drop; - } - tv = VAttachVolumeByName(&error, pname, volname, V_READONLY); - if (error) { - pntr->status = 0; /*things are messed up */ - strcpy(pntr->name, volname); - pntr->volid = volid; - Log("1 Volser: ListVolumes: Could not attach volume %u (%s) error=%d\n", volid, volname, error); - goto drop; - } - if (tv->header->diskstuff.needsSalvaged) { - /*this volume will be salvaged */ - pntr->status = 0; - strcpy(pntr->name, volname); - pntr->volid = volid; - Log("1 Volser: ListVolumes: Volume %u (%s) needs to be salvaged\n", volid, volname); - goto drop; - } - - if (tv->header->diskstuff.destroyMe == DESTROY_ME) { - /*this volume will be salvaged */ - goto drop2; - } - /*read in the relevant info */ - pntr->status = VOK; /*its ok */ - pntr->volid = tv->header->diskstuff.id; - strcpy(pntr->name, tv->header->diskstuff.name); - pntr->type = tv->header->diskstuff.type; /*if ro volume */ - pntr->cloneID = tv->header->diskstuff.cloneId; /*if rw volume */ - pntr->backupID = tv->header->diskstuff.backupId; - pntr->parentID = tv->header->diskstuff.parentId; - pntr->copyDate = tv->header->diskstuff.copyDate; - pntr->inUse = tv->header->diskstuff.inUse; - pntr->size = tv->header->diskstuff.diskused; - pntr->needsSalvaged = tv->header->diskstuff.needsSalvaged; - pntr->maxquota = tv->header->diskstuff.maxquota; - pntr->filecount = tv->header->diskstuff.filecount; - now = FT_ApproxTime(); - if (now - tv->header->diskstuff.dayUseDate > OneDay) - pntr->dayUse = 0; - else - pntr->dayUse = tv->header->diskstuff.dayUse; - pntr->creationDate = tv->header->diskstuff.creationDate; - pntr->accessDate = tv->header->diskstuff.accessDate; - pntr->updateDate = tv->header->diskstuff.updateDate; - pntr->backupDate = tv->header->diskstuff.backupDate; - pntr->spare0 = tv->header->diskstuff.minquota; - pntr->spare1 = - (long)tv->header->diskstuff.weekUse[0] + - (long)tv->header->diskstuff.weekUse[1] + - (long)tv->header->diskstuff.weekUse[2] + - (long)tv->header->diskstuff.weekUse[3] + - (long)tv->header->diskstuff.weekUse[4] + - (long)tv->header->diskstuff.weekUse[5] + - (long)tv->header->diskstuff.weekUse[6]; - pntr->flags = pntr->spare2 = pntr->spare3 = (long)0; - VDetachVolume(&error, tv); /*free the volume */ - tv = (Volume *) 0; - if (error) { - pntr->status = 0; /*things are messed up */ - strcpy(pntr->name, volname); - Log("1 Volser: ListVolumes: Could not detach volume %s\n", - volname); - goto drop; - } - } else { - pntr->volid = volid; - /*just volids are needed */ - } - - drop: - if (ttc) { - DeleteTrans(ttc); - ttc = (struct volser_trans *)0; - } - pntr++; - volumeInfo->volEntries_len += 1; - if ((allocSize - volumeInfo->volEntries_len) < 5) { - /*running out of space, allocate more space */ - allocSize = (allocSize * 3) / 2; - pntr = - (volintInfo *) realloc((char *)volumeInfo->volEntries_val, - allocSize * sizeof(volintInfo)); - if (pntr == NULL) { - if (tv) { - VDetachVolume(&error, tv); - tv = (Volume *) 0; - } - if (ttc) { - DeleteTrans(ttc); - ttc = (struct volser_trans *)0; - } - closedir(dirp); - return VOLSERNO_MEMORY; - } - volumeInfo->volEntries_val = pntr; /* point to new block */ - /* set pntr to the right position */ - pntr = volumeInfo->volEntries_val + volumeInfo->volEntries_len; - - } - - drop2: - if (tv) { - VDetachVolume(&error, tv); - tv = (Volume *) 0; - } - if (ttc) { - DeleteTrans(ttc); - ttc = (struct volser_trans *)0; - } - GetNextVol(dirp, volname, &volid); - - } - closedir(dirp); - if (ttc) - DeleteTrans(ttc); - - return 0; -} - -/*------------------------------------------------------------------------ - * EXPORTED SAFSVolXListVolumes - * - * Description: - * Returns all the volumes on partition a_partID. If a_flags - * is set to 1, then all the relevant extended volume information - * is also returned. - * - * Arguments: - * a_rxCidP : Pointer to the Rx call we're performing. - * a_partID : Partition for which we want the extended list. - * a_flags : Various flags. - * a_volumeXInfoP : Ptr to the extended info blob. - * - * Returns: - * 0 Successful operation - * VOLSERILLEGAL_PARTITION if we got a bogus partition ID - * VOLSERNO_MEMORY if we ran out of memory allocating - * our return blob - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -afs_int32 -SAFSVolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID, - afs_int32 a_flags, volXEntries *a_volumeXInfoP) -{ - afs_int32 code; - - code = VolXListVolumes(a_rxCidP, a_partID, a_flags, a_volumeXInfoP); - osi_auditU(a_rxCidP, VS_XLstVolEvent, code, AUD_END); - return code; -} - -afs_int32 -VolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID, - afs_int32 a_flags, volXEntries *a_volumeXInfoP) -{ /*SAFSVolXListVolumes */ - - volintXInfo *xInfoP; /*Ptr to the extended vol info */ - register struct Volume *tv; /*Volume ptr */ - struct DiskPartition *partP; /*Ptr to partition */ - struct volser_trans *ttc; /*Volume transaction ptr */ - afs_int32 allocSize = 1000; /*To be changed to a larger figure */ - char pname[9], volname[20]; /*Partition, volume names */ - afs_int32 error = 0; /*Return code */ - DIR *dirp; /*Partition directory ptr */ - afs_int32 volid; /*Current volume ID */ - struct VolumeDiskData *volDiskDataP; /*Ptr to on-disk volume data */ - int numStatBytes; /*Num stat bytes to copy per volume */ - unsigned int now; - - /* - * Allocate a large array of extended volume info structures, then - * set it up for action. - */ - a_volumeXInfoP->volXEntries_val = - (volintXInfo *) malloc(allocSize * sizeof(volintXInfo)); - xInfoP = a_volumeXInfoP->volXEntries_val; - a_volumeXInfoP->volXEntries_len = 0; - - /* - * If the partition name we've been given is bad, bogue out. - */ - if (GetPartName(a_partID, pname)) - return (VOLSERILLEGAL_PARTITION); - - /* - * Open the directory representing the given AFS parttion. If we can't - * do that, we lose. - */ - if (!(partP = VGetPartition(pname, 0))) - return VOLSERILLEGAL_PARTITION; - dirp = opendir(VPartitionPath(partP)); - if (dirp == NULL) - return (VOLSERILLEGAL_PARTITION); - - /* - * Sweep through the partition directory, acting on each entry. First, - * of course, figure out how many stat bytes to copy out of each volume. - */ - numStatBytes = - 4 * ((2 * VOLINT_STATS_NUM_RWINFO_FIELDS) + - (4 * VOLINT_STATS_NUM_TIME_FIELDS)); - strcpy(volname, ""); - while (strcmp(volname, "EOD")) { - ttc = (struct volser_trans *)0; /*New one for each pass */ - tv = (Volume *) 0; /*Volume not yet attached */ - - /* - * If this is not a volume, move on to the next entry in the - * partition's directory. - */ - if (!strcmp(volname, "")) { - GetNextVol(dirp, volname, &volid); - continue; - } - - if (a_flags) { - /* - * Full info about the volume desired. Poll to make sure the - * client doesn't time out, then start up a new transaction. - */ -#ifndef AFS_PTHREAD_ENV - IOMGR_Poll(); -#endif - ttc = NewTrans(volid, a_partID); - if (!ttc) { - /* - * Couldn't get a transaction on this volume; let our caller - * know it's busy. - */ - xInfoP->status = VBUSY; - xInfoP->volid = volid; - goto drop; - } - - /* - * Attach the volume, give up on this volume if we can't. - */ - tv = VAttachVolumeByName(&error, pname, volname, V_READONLY); - if (error) { - xInfoP->status = 0; /*things are messed up */ - strcpy(xInfoP->name, volname); - xInfoP->volid = volid; - Log("1 Volser: XListVolumes: Could not attach volume %u\n", - volid); - goto drop; - } - - /* - * Also bag out on this volume if it's been marked as needing a - * salvage or to-be-destroyed. - */ - volDiskDataP = &(tv->header->diskstuff); - if (volDiskDataP->needsSalvaged) { - xInfoP->status = 0; - strcpy(xInfoP->name, volname); - xInfoP->volid = volid; - Log("1 Volser: XListVolumes: Volume %u needs to be salvaged\n", volid); - goto drop; - } - - if (volDiskDataP->destroyMe == DESTROY_ME) - goto drop2; - - /* - * Pull out the desired info and stuff it into the area we'll be - * returning to our caller. - */ - strcpy(xInfoP->name, volDiskDataP->name); - xInfoP->volid = volDiskDataP->id; - xInfoP->type = volDiskDataP->type; - xInfoP->backupID = volDiskDataP->backupId; - xInfoP->parentID = volDiskDataP->parentId; - xInfoP->cloneID = volDiskDataP->cloneId; - xInfoP->status = VOK; - xInfoP->copyDate = volDiskDataP->copyDate; - xInfoP->inUse = volDiskDataP->inUse; - xInfoP->creationDate = volDiskDataP->creationDate; - xInfoP->accessDate = volDiskDataP->accessDate; - xInfoP->updateDate = volDiskDataP->updateDate; - xInfoP->backupDate = volDiskDataP->backupDate; - now = FT_ApproxTime(); - if (now - volDiskDataP->dayUseDate > OneDay) - xInfoP->dayUse = 0; - else - xInfoP->dayUse = volDiskDataP->dayUse; - xInfoP->filecount = volDiskDataP->filecount; - xInfoP->maxquota = volDiskDataP->maxquota; - xInfoP->size = volDiskDataP->diskused; - - /* - * Copy out the stat fields in a single operation. - */ - memcpy((char *)&(xInfoP->stat_reads[0]), - (char *)&(volDiskDataP->stat_reads[0]), numStatBytes); - - /* - * We're done copying. Detach the volume and iterate. - */ - VDetachVolume(&error, tv); - tv = (Volume *) 0; - if (error) { - xInfoP->status = 0; - strcpy(xInfoP->name, volname); - Log("1 Volser: XListVolumes: Could not detach volume %s\n", - volname); - goto drop; - } - } /*Full contents desired */ - else - /* - * Just volume IDs are needed. - */ - xInfoP->volid = volid; - - drop: - /* - * Drop the transaction we have for this volume. - */ - if (ttc) { - DeleteTrans(ttc); - ttc = (struct volser_trans *)0; - } - - /* - * Bump the pointer in the data area we're building, along with - * the count of the number of entries it contains. - */ - xInfoP++; - (a_volumeXInfoP->volXEntries_len)++; - if ((allocSize - a_volumeXInfoP->volXEntries_len) < 5) { - /* - * We're running out of space in the area we've built. Grow it. - */ - allocSize = (allocSize * 3) / 2; - xInfoP = (volintXInfo *) - realloc((char *)a_volumeXInfoP->volXEntries_val, - (allocSize * sizeof(volintXInfo))); - if (xInfoP == NULL) { - /* - * Bummer, no memory. Bag it, tell our caller what went wrong. - */ - if (tv) { - VDetachVolume(&error, tv); - tv = (Volume *) 0; - } - if (ttc) { - DeleteTrans(ttc); - ttc = (struct volser_trans *)0; - } - closedir(dirp); - return (VOLSERNO_MEMORY); - } - - /* - * Memory reallocation worked. Correct our pointers so they - * now point to the new block and the current open position within - * the new block. - */ - a_volumeXInfoP->volXEntries_val = xInfoP; - xInfoP = - a_volumeXInfoP->volXEntries_val + - a_volumeXInfoP->volXEntries_len; - } - /*Need more space */ - drop2: - /* - * Detach our current volume and the transaction on it, then move on - * to the next volume in the partition directory. - */ - if (tv) { - VDetachVolume(&error, tv); - tv = (Volume *) 0; - } - if (ttc) { - DeleteTrans(ttc); - ttc = (struct volser_trans *)0; - } - GetNextVol(dirp, volname, &volid); - } /*Sweep through the partition directory */ - - /* - * We've examined all entries in the partition directory. Close it, - * delete our transaction (if any), and go home happy. - */ - closedir(dirp); - if (ttc) - DeleteTrans(ttc); - return (0); - -} /*SAFSVolXListVolumes */ - -/*this call is used to monitor the status of volser for debugging purposes. - *information about all the active transactions is returned in transInfo*/ -afs_int32 -SAFSVolMonitor(struct rx_call *acid, transDebugEntries *transInfo) -{ - afs_int32 code; - - code = VolMonitor(acid, transInfo); - osi_auditU(acid, VS_MonitorEvent, code, AUD_END); - return code; -} - -afs_int32 -VolMonitor(struct rx_call *acid, transDebugEntries *transInfo) -{ - transDebugInfo *pntr; - afs_int32 allocSize = 50; - struct volser_trans *tt, *allTrans; - - transInfo->transDebugEntries_val = - (transDebugInfo *) malloc(allocSize * sizeof(transDebugInfo)); - pntr = transInfo->transDebugEntries_val; - transInfo->transDebugEntries_len = 0; - allTrans = TransList(); - if (allTrans == (struct volser_trans *)0) - return 0; /*no active transactions */ - for (tt = allTrans; tt; tt = tt->next) { /*copy relevant info into pntr */ - pntr->tid = tt->tid; - pntr->time = tt->time; - pntr->creationTime = tt->creationTime; - pntr->returnCode = tt->returnCode; - pntr->volid = tt->volid; - pntr->partition = tt->partition; - pntr->iflags = tt->iflags; - pntr->vflags = tt->vflags; - pntr->tflags = tt->tflags; - strcpy(pntr->lastProcName, tt->lastProcName); - pntr->callValid = 0; - if (tt->rxCallPtr) { /*record call related info */ - pntr->callValid = 1; - pntr->readNext = tt->rxCallPtr->rnext; - pntr->transmitNext = tt->rxCallPtr->tnext; - pntr->lastSendTime = tt->rxCallPtr->lastSendTime; - pntr->lastReceiveTime = tt->rxCallPtr->lastReceiveTime; - } - pntr++; - transInfo->transDebugEntries_len += 1; - if ((allocSize - transInfo->transDebugEntries_len) < 5) { /*alloc some more space */ - allocSize = (allocSize * 3) / 2; - pntr = - (transDebugInfo *) realloc((char *)transInfo-> - transDebugEntries_val, - allocSize * - sizeof(transDebugInfo)); - transInfo->transDebugEntries_val = pntr; - pntr = - transInfo->transDebugEntries_val + - transInfo->transDebugEntries_len; - /*set pntr to right position */ - } - - } - - return 0; -} - -afs_int32 -SAFSVolSetIdsTypes(struct rx_call *acid, afs_int32 atid, char name[], afs_int32 type, afs_int32 pId, afs_int32 cloneId, afs_int32 backupId) -{ - afs_int32 code; - - code = VolSetIdsTypes(acid, atid, name, type, pId, cloneId, backupId); - osi_auditU(acid, VS_SetIdTyEvent, code, AUD_LONG, atid, AUD_STR, name, - AUD_STR, type, AUD_LONG, pId, AUD_LONG, cloneId, AUD_LONG, - backupId, AUD_END); - return code; -} - -afs_int32 -VolSetIdsTypes(struct rx_call *acid, afs_int32 atid, char name[], afs_int32 type, afs_int32 pId, afs_int32 cloneId, afs_int32 backupId) -{ - struct Volume *tv; - afs_int32 error = 0; - register struct volser_trans *tt; - char caller[MAXKTCNAMELEN]; - - if (strlen(name) > 31) - return VOLSERBADNAME; - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - /* find the trans */ - tt = FindTrans(atid); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolSetIds: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "SetIdsTypes"); - tt->rxCallPtr = acid; - tv = tt->volume; - - V_type(tv) = type; - V_backupId(tv) = backupId; - V_cloneId(tv) = cloneId; - V_parentId(tv) = pId; - strcpy((&V_disk(tv))->name, name); - VUpdateVolume(&error, tv); - if (error) { - Log("1 Volser: SetIdsTypes: VUpdate failed code %d\n", error); - LogError(error); - goto fail; - } - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt) && !error) - return VOLSERTRELE_ERROR; - - return error; - fail: - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt) && !error) - return VOLSERTRELE_ERROR; - return error; -} - -afs_int32 -SAFSVolSetDate(struct rx_call *acid, afs_int32 atid, afs_int32 cdate) -{ - afs_int32 code; - - code = VolSetDate(acid, atid, cdate); - osi_auditU(acid, VS_SetDateEvent, code, AUD_LONG, atid, AUD_LONG, cdate, - AUD_END); - return code; -} - -afs_int32 -VolSetDate(struct rx_call *acid, afs_int32 atid, afs_int32 cdate) -{ - struct Volume *tv; - afs_int32 error = 0; - register struct volser_trans *tt; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - /* find the trans */ - tt = FindTrans(atid); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - Log("1 Volser: VolSetDate: volume %u has been deleted \n", tt->volid); - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "SetDate"); - tt->rxCallPtr = acid; - tv = tt->volume; - - V_creationDate(tv) = cdate; - VUpdateVolume(&error, tv); - if (error) { - Log("1 Volser: SetDate: VUpdate failed code %d\n", error); - LogError(error); - goto fail; - } - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt) && !error) - return VOLSERTRELE_ERROR; - - return error; - fail: - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt) && !error) - return VOLSERTRELE_ERROR; - return error; -} - -#ifdef AFS_NAMEI_ENV -/* - * Inode number format (from namei_ops.c): - * low 26 bits - vnode number - all 1's if volume special file. - * next 3 bits - tag - * next 3 bits spare (0's) - * high 32 bits - uniquifier (regular) or type if spare - */ -#define NAMEI_VNODEMASK 0x003ffffff -#define NAMEI_TAGMASK 0x7 -#define NAMEI_TAGSHIFT 26 -#define NAMEI_UNIQMASK 0xffffffff -#define NAMEI_UNIQSHIFT 32 -#define NAMEI_INODESPECIAL ((Inode)NAMEI_VNODEMASK) -#define NAMEI_VNODESPECIAL NAMEI_VNODEMASK -#endif /* AFS_NAMEI_ENV */ - -afs_int32 -SAFSVolConvertROtoRWvolume(struct rx_call *acid, afs_int32 partId, - afs_int32 volumeId) -{ -#if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV) - DIR *dirp; - char pname[16]; - char volname[20]; - afs_int32 error = 0; - afs_int32 volid; - int found = 0; - char caller[MAXKTCNAMELEN]; - char headername[16]; - char opath[256]; - char npath[256]; - struct VolumeDiskHeader h; - int fd; - IHandle_t *ih; - Inode ino; - struct DiskPartition *dp; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - if (GetPartName(partId, pname)) - return VOLSERILLEGAL_PARTITION; - dirp = opendir(pname); - if (dirp == NULL) - return VOLSERILLEGAL_PARTITION; - strcpy(volname, ""); - - while (strcmp(volname, "EOD") && !found) { /*while there are more volumes in the partition */ - GetNextVol(dirp, volname, &volid); - if (strcmp(volname, "")) { /* its a volume */ - if (volid == volumeId) - found = 1; - } - } - if (!found) - return ENOENT; - (void)afs_snprintf(headername, sizeof headername, VFORMAT, volumeId); - (void)afs_snprintf(opath, sizeof opath, "%s/%s", pname, headername); - fd = open(opath, O_RDONLY); - if (fd < 0) { - Log("1 SAFS_VolConvertROtoRWvolume: Couldn't open header for RO-volume %lu.\n", volumeId); - return ENOENT; - } - if (read(fd, &h, sizeof(h)) != sizeof(h)) { - Log("1 SAFS_VolConvertROtoRWvolume: Couldn't read header for RO-volume %lu.\n", volumeId); - close(fd); - return EIO; - } - close(fd); - FSYNC_askfs(volumeId, pname, FSYNC_RESTOREVOLUME, 0); - - for (dp = DiskPartitionList; dp && strcmp(dp->name, pname); - dp = dp->next); - if (!dp) { - Log("1 SAFS_VolConvertROtoRWvolume: Couldn't find DiskPartition for %s\n", pname); - return EIO; - } - ino = namei_MakeSpecIno(h.parent, VI_LINKTABLE); - IH_INIT(ih, dp->device, h.parent, ino); - - error = namei_ConvertROtoRWvolume(ih, volumeId); - if (error) - return error; - h.id = h.parent; - h.volumeInfo_hi = h.id; - h.smallVnodeIndex_hi = h.id; - h.largeVnodeIndex_hi = h.id; - h.linkTable_hi = h.id; - (void)afs_snprintf(headername, sizeof headername, VFORMAT, h.id); - (void)afs_snprintf(npath, sizeof npath, "%s/%s", pname, headername); - fd = open(npath, O_CREAT | O_EXCL | O_RDWR, 0644); - if (fd < 0) { - Log("1 SAFS_VolConvertROtoRWvolume: Couldn't create header for RW-volume %lu.\n", h.id); - return EIO; - } - if (write(fd, &h, sizeof(h)) != sizeof(h)) { - Log("1 SAFS_VolConvertROtoRWvolume: Couldn't write header for RW-volume %lu.\n", h.id); - close(fd); - return EIO; - } - close(fd); - if (unlink(opath) < 0) { - Log("1 SAFS_VolConvertROtoRWvolume: Couldn't unlink RO header, error = %d\n", error); - } - FSYNC_askfs(volumeId, pname, FSYNC_DONE, 0); - FSYNC_askfs(h.id, pname, FSYNC_ON, 0); - return 0; -#else /* AFS_NAMEI_ENV */ - return EINVAL; -#endif /* AFS_NAMEI_ENV */ -} - -afs_int32 -SAFSVolGetSize(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, - register struct volintSize *size) -{ - int code = 0; - register struct volser_trans *tt; - char caller[MAXKTCNAMELEN]; - - if (!afsconf_SuperUser(tdir, acid, caller)) - return VOLSERBAD_ACCESS; /*not a super user */ - tt = FindTrans(fromTrans); - if (!tt) - return ENOENT; - if (tt->vflags & VTDeleted) { - TRELE(tt); - return ENOENT; - } - strcpy(tt->lastProcName, "GetSize"); - tt->rxCallPtr = acid; - code = SizeDumpVolume(acid, tt->volume, fromDate, 1, size); /* measure volume's data */ - tt->rxCallPtr = (struct rx_call *)0; - if (TRELE(tt)) - return VOLSERTRELE_ERROR; - -/* osi_auditU(acid, VS_DumpEvent, code, AUD_LONG, fromTrans, AUD_END); */ - return code; -} - -/* GetPartName - map partid (a decimal number) into pname (a string) - * Since for NT we actually want to return the drive name, we map through the - * partition struct. - */ -static int -GetPartName(afs_int32 partid, char *pname) -{ - if (partid < 0) - return -1; - if (partid < 26) { - strcpy(pname, "/vicep"); - pname[6] = 'a' + partid; - pname[7] = '\0'; - return 0; - } else if (partid < VOLMAXPARTS) { - strcpy(pname, "/vicep"); - partid -= 26; - pname[6] = 'a' + (partid / 26); - pname[7] = 'a' + (partid % 26); - pname[8] = '\0'; - return 0; - } else - return -1; -} diff --git a/src/volser/volser.p.h b/src/volser/volser.p.h deleted file mode 100644 index 091b523b8..000000000 --- a/src/volser/volser.p.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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 - */ - -#ifndef _VOLSER_ -#define _VOLSER_ 1 - -#ifdef AFS_PTHREAD_ENV -#include -#include -#endif - -/* vflags, representing state of the volume */ -#define VTDeleteOnSalvage 1 /* delete on next salvage */ -#define VTOutOfService 2 /* never put this volume online */ -#define VTDeleted 4 /* deleted, don't do anything else */ - -/* iflags, representing "attach mode" for this volume at the start of this transaction */ -#define ITOffline 1 /* volume offline on server (returns VOFFLINE) */ -#define ITBusy 2 /* volume busy on server (returns VBUSY) */ -#define ITReadOnly 8 /* volume readonly on client, readwrite on server -DO NOT USE */ -#define ITCreate 0x10 /* volume does not exist correctly yet */ -#define ITCreateVolID 0x1000 /* create volid */ - -/* tflags, representing transaction state */ -#define TTDeleted 1 /* delete transaction not yet freed due to high refCount */ - -/* other names for volumes in voldefs.h */ -#define volser_RW 0 -#define volser_RO 1 -#define volser_BACK 2 - -#define THOLD(tt) ((tt)->refCount++) - -struct volser_trans { - struct volser_trans *next; /* next ptr in active trans list */ - afs_int32 tid; /* transaction id */ - afs_int32 time; /* time transaction was last active (for timeouts) */ - afs_int32 creationTime; /* time the transaction started */ - afs_int32 returnCode; /* transaction error code */ - struct Volume *volume; /* pointer to open volume */ - afs_int32 volid; /* open volume's id */ - afs_int32 partition; /* open volume's partition */ - afs_int32 dumpTransId; /* other side's trans id during a dump */ - afs_int32 dumpSeq; /* next sequence number to use during a dump */ - short refCount; /* reference count on this structure */ - short iflags; /* initial attach mode flags (IT*) */ - char vflags; /* current volume status flags (VT*) */ - char tflags; /* transaction flags (TT*) */ - char incremental; /* do an incremental restore */ - /* the fields below are useful for debugging */ - char lastProcName[30]; /* name of the last procedure which used transaction */ - struct rx_call *rxCallPtr; /* pointer to latest associated rx_call */ - -}; - -/* This is how often the garbage collection thread wakes up and - * checks for transactions that have timed out: BKGLoop() - */ -#define GCWAKEUP 30 - -struct volser_dest { - afs_int32 destHost; - afs_int32 destPort; - afs_int32 destSSID; -}; - -#define MAXHELPERS 10 -/* flags for vol helper busyFlags array. First, VHIdle goes on when a server - * becomes idle. Next, idle flag is cleared and VHRequest goes on when - * trans is queued. Finally, VHRequest goes off (but VHIdle stays off) when - * helper is done. VHIdle goes on again when an lwp waits for work. - */ -#define VHIdle 1 /* vol helper is waiting for a request here */ -#define VHRequest 2 /* a request has been queued here */ -extern struct volser_trans *QI_GlobalWriteTrans; - -/* the stuff below is from errors.h in vol directory */ -#define VICE_SPECIAL_ERRORS 101 /* Lowest special error code */ - -#define VSALVAGE 101 /* Volume needs salvage */ -#define VNOVNODE 102 /* Bad vnode number quoted */ -#define VNOVOL 103 /* Volume not attached, doesn't exist, - * not created or not online */ -#define VVOLEXISTS 104 /* Volume already exists */ -#define VNOSERVICE 105 /* Volume is not in service (i.e. it's - * is out of funds, is obsolete, or somesuch) */ -#define VOFFLINE 106 /* Volume is off line, for the reason - * given in the offline message */ -#define VONLINE 107 /* Volume is already on line */ -#define VDISKFULL 108 /* Partition is "full", i.e. rougly within - * n% of full */ -#define VOVERQUOTA 109 /* Volume max quota exceeded */ -#define VBUSY 110 /* Volume temporarily unavailable; try again. - * The volume should be available again shortly; if - * it isn't something is wrong. Not normally to be - * propagated to the application level */ -#define VMOVED 111 /* Volume has moved to another server; do a VGetVolumeInfo - * to THIS server to find out where */ - -#define MyPort 5003 -#define NameLen 80 -#define VLDB_MAXSERVERS 10 -#define VOLSERVICE_ID 4 -#define INVALID_BID 0 -#define VOLSER_MAXVOLNAME 65 -#define VOLSER_OLDMAXVOLNAME 32 -#define VOLMAXPARTS 255 - -/*flags used for interfacing with the backup system */ -struct volDescription { /*used for interfacing with the backup system */ - char volName[VOLSER_MAXVOLNAME]; /* should be VNAMESIZE as defined in volume.h */ - afs_int32 volId; - int volSize; - afs_int32 volFlags; - afs_int32 volCloneId; -}; - -struct partList { /*used by the backup system */ - afs_int32 partId[VOLMAXPARTS]; - afs_int32 partFlags[VOLMAXPARTS]; -}; - -#define STDERR stderr -#define STDOUT stdout - -#define ISNAMEVALID(name) (strlen(name) < (VOLSER_OLDMAXVOLNAME - 9)) - -/* values for flags in struct nvldbEntry */ -#define RW_EXISTS 0x1000 -#define RO_EXISTS 0x2000 -#define BACK_EXISTS 0x4000 - -/* values for serverFlags in struct nvldbEntry */ -#define NEW_REPSITE 0x01 -#define ITSROVOL 0x02 -#define ITSRWVOL 0x04 -#define ITSBACKVOL 0x08 -#define RO_DONTUSE 0x20 - -#define VLOP_RESTORE 0x100 /*this is bogus, clashes with VLOP_DUMP */ -#define VLOP_ADDSITE 0x80 /*this is bogus, clashes with VLOP_DELETE */ -#define PARTVALID 0x01 -#define CLONEVALID 0x02 -#define CLONEZAPPED 0x04 -#define IDVALID 0x08 -#define NAMEVALID 0x10 -#define SIZEVALID 0x20 -#define ENTRYVALID 0x40 -#define REUSECLONEID 0x80 -#define VOK 0x02 - -/* Values for the UV_RestoreVolume flags parameter */ -/* Also used for UV_CopyVolume and UV_CloneVolume */ -#define RV_FULLRST 0x1 -#define RV_OFFLINE 0x2 -#define RV_RDONLY 0x10000 -#define RV_CPINCR 0x20000 -#define RV_NOVLDB 0x40000 -#define RV_NOCLONE 0x80000 - -extern afs_uint32 vsu_GetVolumeID(char *astring, struct ubik_client *acstruct, afs_int32 *errp); -extern int vsu_ExtractName(char rname[], char name[]); -extern afs_int32 vsu_ClientInit(int noAuthFlag, char *confDir, char *cellName, afs_int32 sauth, struct ubik_client **uclientp, int (*secproc)()); -extern void vsu_SetCrypt(int cryptflag); - -#endif /* _VOLSER_ */ diff --git a/src/volser/volserver.rc b/src/volser/volserver.rc deleted file mode 100644 index 074216fa8..000000000 --- a/src/volser/volserver.rc +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 - */ - -/* Define VERSIONINFO resource */ - -#define AFS_VERINFO_FILE_DESCRIPTION "AFS Volume Server" -#define AFS_VERINFO_NAME "volserver" -#define AFS_VERINFO_FILENAME "volserver.exe" - -#include "AFS_component_version_number.h" -#include "..\config\NTVersioninfo.rc" diff --git a/src/volser/voltrans.c b/src/volser/voltrans.c deleted file mode 100644 index 4c28fbec0..000000000 --- a/src/volser/voltrans.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * 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 - */ - -/* - * Module: Voltrans.c - * System: Volser - * Instituition: ITC, CMU - * Date: December, 88 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/voltrans.c,v 1.10 2003/11/22 02:57:04 shadow Exp $"); - -#ifdef AFS_NT40_ENV -#include -#else -#include -#endif - -#include -#include -#include -#ifdef AFS_NT40_ENV -#include -#include -#else -#include -#include -#include -#endif -#include -#include -#include -#include -#ifdef AFS_PTHREAD_ENV -#include -#else /* AFS_PTHREAD_ENV */ -#include -#endif /* AFS_PTHREAD_ENV */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef AFS_NT40_ENV -#include -#endif -#include -#include - -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif - -#include "volser.h" - -/*@printflike@*/ extern void Log(const char *format, ...); - -static struct volser_trans *allTrans = 0; -static afs_int32 transCounter = 1; - -/* create a new transaction, returning ptr to same with high ref count */ -struct volser_trans * -NewTrans(avol, apart) - afs_int32 avol; - afs_int32 apart; -{ - /* set volid, next, partition */ - register struct volser_trans *tt; - struct timeval tp; - struct timezone tzp; - - VTRANS_LOCK; - /* don't allow the same volume to be attached twice */ - for (tt = allTrans; tt; tt = tt->next) { - if ((tt->volid == avol) && (tt->partition == apart)) { - VTRANS_UNLOCK; - return (struct volser_trans *)0; /* volume busy */ - } - } - VTRANS_UNLOCK; - tt = (struct volser_trans *)malloc(sizeof(struct volser_trans)); - memset(tt, 0, sizeof(struct volser_trans)); - tt->volid = avol; - tt->partition = apart; - tt->refCount = 1; - tt->rxCallPtr = (struct rx_call *)0; - strcpy(tt->lastProcName, ""); - gettimeofday(&tp, &tzp); - tt->creationTime = tp.tv_sec; - tt->time = FT_ApproxTime(); - VTRANS_LOCK; - tt->tid = transCounter++; - tt->next = allTrans; - allTrans = tt; - VTRANS_UNLOCK; - return tt; -} - -/* find a trans, again returning with high ref count */ -struct volser_trans * -FindTrans(atrans) - register afs_int32 atrans; -{ - register struct volser_trans *tt; - VTRANS_LOCK; - for (tt = allTrans; tt; tt = tt->next) { - if (tt->tid == atrans) { - tt->time = FT_ApproxTime(); - tt->refCount++; - VTRANS_UNLOCK; - return tt; - } - } - VTRANS_UNLOCK; - return (struct volser_trans *)0; -} - -/* delete transaction if refcount == 1, otherwise queue delete for later. Does implicit TRELE */ -DeleteTrans(atrans) - register struct volser_trans *atrans; -{ - register struct volser_trans *tt, **lt; - afs_int32 error; - - if (atrans->refCount > 1) { - /* someone else is using it now */ - atrans->refCount--; - atrans->tflags |= TTDeleted; - return 0; - } - - /* otherwise we zap it ourselves */ - VTRANS_LOCK; - lt = &allTrans; - for (tt = *lt; tt; lt = &tt->next, tt = *lt) { - if (tt == atrans) { - if (tt->volume) - VDetachVolume(&error, tt->volume); - tt->volume = NULL; - *lt = tt->next; - free(tt); - VTRANS_UNLOCK; - return 0; - } - } - VTRANS_UNLOCK; - return -1; /* failed to find the transaction in the generic list */ -} - -/* THOLD is a macro defined in volser.h */ - -/* put a transaction back */ -TRELE(at) - register struct volser_trans *at; -{ - if (at->refCount == 0) { - Log("TRELE: bad refcount\n"); - return VOLSERTRELE_ERROR; - } - - at->time = FT_ApproxTime(); /* we're still using it */ - if (at->refCount == 1 && (at->tflags & TTDeleted)) { - DeleteTrans(at); - return 0; - } - /* otherwise simply drop refcount */ - at->refCount--; - return 0; -} - -/* look for old transactions and delete them */ -#define OLDTRANSTIME 600 /* seconds */ -#define OLDTRANSWARN 300 /* seconds */ -static int GCDeletes = 0; -GCTrans() -{ - register struct volser_trans *tt, *nt; - afs_int32 now; - - now = FT_ApproxTime(); - - VTRANS_LOCK; - for (tt = allTrans; tt; tt = nt) { - nt = tt->next; /* remember in case we zap it */ - if (tt->time + OLDTRANSWARN < now) { - Log("trans %u on volume %u %s than %d seconds\n", tt->tid, - tt->volid, - ((tt->refCount > 0) ? "is older" : "has been idle for more"), - (((now - tt->time) / GCWAKEUP) * GCWAKEUP)); - } - if (tt->refCount > 0) - continue; - if (tt->time + OLDTRANSTIME < now) { - Log("trans %u on volume %u has timed out\n", tt->tid, tt->volid); - tt->refCount++; /* we're using it now */ - DeleteTrans(tt); /* drops refCount or deletes it */ - GCDeletes++; - } - } - VTRANS_UNLOCK; - return 0; -} - -/*return the head of the transaction list */ -struct volser_trans * -TransList() -{ - return (allTrans); -} diff --git a/src/volser/vos.c b/src/volser/vos.c deleted file mode 100644 index 23689f03c..000000000 --- a/src/volser/vos.c +++ /dev/null @@ -1,5593 +0,0 @@ -/* - * 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 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/vos.c,v 1.38 2004/04/08 22:20:39 jaltman Exp $"); - -#include -#ifdef AFS_NT40_ENV -#include -#include -#include -#else -#include -#include -#include -#include -#include -#endif -#include -#ifdef AFS_AIX_ENV -#include -#endif -#include - -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "volser.h" -#include "volint.h" -#include "lockdata.h" -#ifdef AFS_AIX32_ENV -#include -#endif -#include "volser_prototypes.h" - -#ifdef HAVE_POSIX_REGEX -#include -#endif - -struct tqElem { - afs_int32 volid; - struct tqElem *next; -}; - -struct tqHead { - afs_int32 count; - struct tqElem *next; -}; - -#define COMMONPARMS cmd_Seek(ts, 12);\ -cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\ -cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\ -cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\ -cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\ -cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\ - -#define ERROR_EXIT(code) {error=(code); goto error_exit;} - -extern int verbose; -int rxInitDone = 0; -struct rx_connection *tconn; -afs_int32 tserver; -extern struct ubik_client *cstruct; -const char *confdir; - -static struct tqHead busyHead, notokHead; - -static void -qInit(struct tqHead *ahead) -{ - memset((char *)ahead, 0, sizeof(struct tqHead)); - return; -} - - -static void -qPut(struct tqHead *ahead, afs_int32 volid) -{ - struct tqElem *elem; - - elem = (struct tqElem *)malloc(sizeof(struct tqElem)); - elem->next = ahead->next; - elem->volid = volid; - ahead->next = elem; - ahead->count++; - return; -} - -static void -qGet(struct tqHead *ahead, afs_int32 *volid) -{ - struct tqElem *tmp; - - if (ahead->count <= 0) - return; - *volid = ahead->next->volid; - tmp = ahead->next; - ahead->next = tmp->next; - ahead->count--; - free(tmp); - return; -} - -/* returns 1 if exists else 0 */ -static int -FileExists(char *filename) -{ - usd_handle_t ufd; - int code; - afs_hyper_t size; - - code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd); - if (code) { - return 0; - } - code = USD_IOCTL(ufd, USD_IOCTL_GETSIZE, &size); - USD_CLOSE(ufd); - if (code) { - return 0; - } - return 1; -} - -/* returns 1 if doesnot end in .readonly or .backup, else 0 */ -static int -VolNameOK(char *name) -{ - int total; - - - total = strlen(name); - if (!strcmp(&name[total - 9], ".readonly")) { - return 0; - } else if (!strcmp(&name[total - 7], ".backup")) { - return 0; - } else { - return 1; - } -} - -/* return 1 if name is a number else 0 */ -static int -IsNumeric(char *name) -{ - int result, len, i; - char *ptr; - - result = 1; - ptr = name; - len = strlen(name); - for (i = 0; i < len; i++) { - if (*ptr < '0' || *ptr > '9') { - result = 0; - break; - } - ptr++; - - } - return result; -} - - -/* - * Parse a server name/address and return the address in HOST BYTE order - */ -afs_int32 -GetServer(char *aname) -{ - register struct hostent *th; - afs_int32 addr; - int b1, b2, b3, b4; - register afs_int32 code; - char hostname[MAXHOSTCHARS]; - - code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4); - if (code == 4) { - addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; - addr = ntohl(addr); /* convert to host order */ - } else { - th = gethostbyname(aname); - if (!th) - return 0; - memcpy(&addr, th->h_addr, sizeof(addr)); - } - - if (addr == htonl(0x7f000001)) { /* local host */ - code = gethostname(hostname, MAXHOSTCHARS); - if (code) - return 0; - th = gethostbyname(hostname); /* returns host byte order */ - if (!th) - return 0; - memcpy(&addr, th->h_addr, sizeof(addr)); - } - - return (addr); -} - -afs_int32 -GetVolumeType(char *aname) -{ - - if (!strcmp(aname, "ro")) - return (ROVOL); - else if (!strcmp(aname, "rw")) - return (RWVOL); - else if (!strcmp(aname, "bk")) - return (BACKVOL); - else - return (-1); -} - -int -IsPartValid(afs_int32 partId, afs_int32 server, afs_int32 *code) -{ - struct partList dummyPartList; - int i, success, cnt; - - success = 0; - *code = 0; - - *code = UV_ListPartitions(server, &dummyPartList, &cnt); - if (*code) - return success; - for (i = 0; i < cnt; i++) { - if (dummyPartList.partFlags[i] & PARTVALID) - if (dummyPartList.partId[i] == partId) - success = 1; - } - return success; -} - - - - /*sends the contents of file associated with and to Rx Stream - * associated with */ -int -SendFile(usd_handle_t ufd, register struct rx_call *call, long blksize) -{ - char *buffer = (char *)0; - afs_int32 error = 0; - int done = 0; - afs_uint32 nbytes; - - buffer = (char *)malloc(blksize); - if (!buffer) { - fprintf(STDERR, "malloc failed\n"); - return -1; - } - - while (!error && !done) { -#ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */ - fd_set in; - FD_ZERO(&in); - FD_SET((int)(ufd->handle), &in); - /* don't timeout if read blocks */ - IOMGR_Select(((int)(ufd->handle)) + 1, &in, 0, 0, 0); -#endif - error = USD_READ(ufd, buffer, blksize, &nbytes); - if (error) { - fprintf(STDERR, "File system read failed\n"); - break; - } - if (nbytes == 0) { - done = 1; - break; - } - if (rx_Write(call, buffer, nbytes) != nbytes) { - error = -1; - break; - } - } - if (buffer) - free(buffer); - return error; -} - -/* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and - * writes it out to the volume. */ -afs_int32 -WriteData(struct rx_call *call, char *rock) -{ - char *filename; - usd_handle_t ufd; - long blksize; - afs_int32 error, code; - int ufdIsOpen = 0; - - error = 0; - - filename = rock; - if (!filename || !*filename) { - usd_StandardInput(&ufd); - blksize = 4096; - ufdIsOpen = 1; - } else { - code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd); - if (code == 0) { - ufdIsOpen = 1; - code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize); - } - if (code) { - fprintf(STDERR, "Could not access file '%s'\n", filename); - error = VOLSERBADOP; - goto wfail; - } - } - code = SendFile(ufd, call, blksize); - if (code) { - error = code; - goto wfail; - } - wfail: - if (ufdIsOpen) { - code = USD_CLOSE(ufd); - if (code) { - fprintf(STDERR, "Could not close dump file %s\n", - (filename && *filename) ? filename : "STDOUT"); - if (!error) - error = code; - } - } - return error; -} - -/* Receive data from stream into file associated - * with - */ -int -ReceiveFile(usd_handle_t ufd, struct rx_call *call, long blksize) -{ - char *buffer = NULL; - afs_int32 bytesread; - afs_uint32 bytesleft, w; - afs_int32 error = 0; - - buffer = (char *)malloc(blksize); - if (!buffer) { - fprintf(STDERR, "memory allocation failed\n"); - ERROR_EXIT(-1); - } - - while ((bytesread = rx_Read(call, buffer, blksize)) > 0) { - for (bytesleft = bytesread; bytesleft; bytesleft -= w) { -#ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */ - fd_set out; - FD_ZERO(&out); - FD_SET((int)(ufd->handle), &out); - /* don't timeout if write blocks */ - IOMGR_Select(((int)(ufd->handle)) + 1, 0, &out, 0, 0); -#endif - error = - USD_WRITE(ufd, &buffer[bytesread - bytesleft], bytesleft, &w); - if (error) { - fprintf(STDERR, "File system write failed\n"); - ERROR_EXIT(-1); - } - } - } - - error_exit: - if (buffer) - free(buffer); - return (error); -} - -afs_int32 -DumpFunction(struct rx_call *call, char *filename) -{ - usd_handle_t ufd; /* default is to stdout */ - afs_int32 error = 0, code; - afs_hyper_t size; - long blksize; - int ufdIsOpen = 0; - - /* Open the output file */ - if (!filename || !*filename) { - usd_StandardOutput(&ufd); - blksize = 4096; - ufdIsOpen = 1; - } else { - code = - usd_Open(filename, USD_OPEN_CREATE | USD_OPEN_RDWR, 0666, &ufd); - if (code == 0) { - ufdIsOpen = 1; - hzero(size); - code = USD_IOCTL(ufd, USD_IOCTL_SETSIZE, &size); - } - if (code == 0) { - code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize); - } - if (code) { - fprintf(STDERR, "Could not create file '%s'\n", filename); - ERROR_EXIT(VOLSERBADOP); - } - } - - code = ReceiveFile(ufd, call, blksize); - if (code) - ERROR_EXIT(code); - - error_exit: - /* Close the output file */ - if (ufdIsOpen) { - code = USD_CLOSE(ufd); - if (code) { - fprintf(STDERR, "Could not close dump file %s\n", - (filename && *filename) ? filename : "STDIN"); - if (!error) - error = code; - } - } - - return (error); -} - -static void -DisplayFormat(pntr, server, part, totalOK, totalNotOK, totalBusy, fast, - longlist, disp) - volintInfo *pntr; - afs_int32 server, part; - int *totalOK, *totalNotOK, *totalBusy; - int fast, longlist, disp; -{ - char pname[10]; - - if (fast) { - fprintf(STDOUT, "%-10lu\n", (unsigned long)pntr->volid); - } else if (longlist) { - if (pntr->status == VOK) { - fprintf(STDOUT, "%-32s ", pntr->name); - fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid); - if (pntr->type == 0) - fprintf(STDOUT, "RW "); - if (pntr->type == 1) - fprintf(STDOUT, "RO "); - if (pntr->type == 2) - fprintf(STDOUT, "BK "); - fprintf(STDOUT, "%10d K ", pntr->size); - if (pntr->inUse == 1) { - fprintf(STDOUT, "On-line"); - *totalOK += 1; - } else { - fprintf(STDOUT, "Off-line"); - *totalNotOK++; - } - if (pntr->needsSalvaged == 1) - fprintf(STDOUT, "**needs salvage**"); - fprintf(STDOUT, "\n"); - MapPartIdIntoName(part, pname); - fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(server), - pname); - fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n", - (unsigned long)pntr->parentID, - (unsigned long)pntr->cloneID, - (unsigned long)pntr->backupID); - fprintf(STDOUT, " MaxQuota %10d K \n", pntr->maxquota); - fprintf(STDOUT, " Creation %s", - ctime((time_t *) & pntr->creationDate)); -#ifdef FULL_LISTVOL_SWITCH - fprintf(STDOUT, " Copy %s", - ctime((time_t *) & pntr->copyDate)); - if (!pntr->backupDate) - fprintf(STDOUT, " Backup Never\n"); - else - fprintf(STDOUT, " Backup %s", - ctime((time_t *) & pntr->backupDate)); - if (pntr->accessDate) - fprintf(STDOUT, " Last Access %s", - ctime((time_t *) & pntr->accessDate)); -#endif - if (pntr->updateDate < pntr->creationDate) - fprintf(STDOUT, " Last Update %s", - ctime((time_t *) & pntr->creationDate)); - else - fprintf(STDOUT, " Last Update %s", - ctime((time_t *) & pntr->updateDate)); - fprintf(STDOUT, - " %d accesses in the past day (i.e., vnode references)\n", - pntr->dayUse); - } else if (pntr->status == VBUSY) { - *totalBusy += 1; - qPut(&busyHead, pntr->volid); - if (disp) - fprintf(STDOUT, "**** Volume %lu is busy ****\n", - (unsigned long)pntr->volid); - } else { - *totalNotOK += 1; - qPut(¬okHead, pntr->volid); - if (disp) - fprintf(STDOUT, "**** Could not attach volume %lu ****\n", - (unsigned long)pntr->volid); - } - fprintf(STDOUT, "\n"); - } else { /* default listing */ - if (pntr->status == VOK) { - fprintf(STDOUT, "%-32s ", pntr->name); - fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid); - if (pntr->type == 0) - fprintf(STDOUT, "RW "); - if (pntr->type == 1) - fprintf(STDOUT, "RO "); - if (pntr->type == 2) - fprintf(STDOUT, "BK "); - fprintf(STDOUT, "%10d K ", pntr->size); - if (pntr->inUse == 1) { - fprintf(STDOUT, "On-line"); - *totalOK += 1; - } else { - fprintf(STDOUT, "Off-line"); - *totalNotOK += 1; - } - if (pntr->needsSalvaged == 1) - fprintf(STDOUT, "**needs salvage**"); - fprintf(STDOUT, "\n"); - } else if (pntr->status == VBUSY) { - *totalBusy += 1; - qPut(&busyHead, pntr->volid); - if (disp) - fprintf(STDOUT, "**** Volume %lu is busy ****\n", - (unsigned long)pntr->volid); - } else { - *totalNotOK += 1; - qPut(¬okHead, pntr->volid); - if (disp) - fprintf(STDOUT, "**** Could not attach volume %lu ****\n", - (unsigned long)pntr->volid); - } - } -} - -/*------------------------------------------------------------------------ - * PRIVATE XDisplayFormat - * - * Description: - * Display the contents of one extended volume info structure. - * - * Arguments: - * a_xInfoP : Ptr to extended volume info struct to print. - * a_servID : Server ID to print. - * a_partID : Partition ID to print. - * a_totalOKP : Ptr to total-OK counter. - * a_totalNotOKP : Ptr to total-screwed counter. - * a_totalBusyP : Ptr to total-busy counter. - * a_fast : Fast listing? - * a_int32 : Int32 listing? - * a_showProblems : Show volume problems? - * - * Returns: - * Nothing. - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -static void -XDisplayFormat(a_xInfoP, a_servID, a_partID, a_totalOKP, a_totalNotOKP, - a_totalBusyP, a_fast, a_int32, a_showProblems) - volintXInfo *a_xInfoP; - afs_int32 a_servID; - afs_int32 a_partID; - int *a_totalOKP; - int *a_totalNotOKP; - int *a_totalBusyP; - int a_fast; - int a_int32; - int a_showProblems; - -{ /*XDisplayFormat */ - - char pname[10]; - - if (a_fast) { - /* - * Short & sweet. - */ - fprintf(STDOUT, "%-10lu\n", (unsigned long)a_xInfoP->volid); - } else if (a_int32) { - /* - * Fully-detailed listing. - */ - if (a_xInfoP->status == VOK) { - /* - * Volume's status is OK - all the fields are valid. - */ - fprintf(STDOUT, "%-32s ", a_xInfoP->name); - fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid); - if (a_xInfoP->type == 0) - fprintf(STDOUT, "RW "); - if (a_xInfoP->type == 1) - fprintf(STDOUT, "RO "); - if (a_xInfoP->type == 2) - fprintf(STDOUT, "BK "); - fprintf(STDOUT, "%10d K used ", a_xInfoP->size); - fprintf(STDOUT, "%d files ", a_xInfoP->filecount); - if (a_xInfoP->inUse == 1) { - fprintf(STDOUT, "On-line"); - (*a_totalOKP)++; - } else { - fprintf(STDOUT, "Off-line"); - (*a_totalNotOKP)++; - } - fprintf(STDOUT, "\n"); - MapPartIdIntoName(a_partID, pname); - fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(a_servID), - pname); - fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n", - (unsigned long)a_xInfoP->parentID, - (unsigned long)a_xInfoP->cloneID, - (unsigned long)a_xInfoP->backupID); - fprintf(STDOUT, " MaxQuota %10d K \n", a_xInfoP->maxquota); - fprintf(STDOUT, " Creation %s", - ctime((time_t *) & a_xInfoP->creationDate)); -#ifdef FULL_LISTVOL_SWITCH - fprintf(STDOUT, " Copy %s", - ctime((time_t *) & a_xInfoP->copyDate)); - if (!a_xInfoP->backupDate) - fprintf(STDOUT, " Backup Never\n"); - else - fprintf(STDOUT, " Backup %s", - ctime((time_t *) & a_xInfoP->backupDate)); - if (a_xInfoP->accessDate) - fprintf(STDOUT, " Last Access %s", - ctime((time_t *) & a_xInfoP->accessDate)); -#endif - if (a_xInfoP->updateDate < a_xInfoP->creationDate) - fprintf(STDOUT, " Last Update %s", - ctime((time_t *) & a_xInfoP->creationDate)); - else - fprintf(STDOUT, " Last Update %s", - ctime((time_t *) & a_xInfoP->updateDate)); - fprintf(STDOUT, - " %d accesses in the past day (i.e., vnode references)\n", - a_xInfoP->dayUse); - - /* - * Print all the read/write and authorship stats. - */ - fprintf(STDOUT, "\n Raw Read/Write Stats\n"); - fprintf(STDOUT, - " |-------------------------------------------|\n"); - fprintf(STDOUT, - " | Same Network | Diff Network |\n"); - fprintf(STDOUT, - " |----------|----------|----------|----------|\n"); - fprintf(STDOUT, - " | Total | Auth | Total | Auth |\n"); - fprintf(STDOUT, - " |----------|----------|----------|----------|\n"); - fprintf(STDOUT, "Reads | %8d | %8d | %8d | %8d |\n", - a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET], - a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH], - a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET], - a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]); - fprintf(STDOUT, "Writes | %8d | %8d | %8d | %8d |\n", - a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET], - a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH], - a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET], - a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]); - fprintf(STDOUT, - " |-------------------------------------------|\n\n"); - - fprintf(STDOUT, - " Writes Affecting Authorship\n"); - fprintf(STDOUT, - " |-------------------------------------------|\n"); - fprintf(STDOUT, - " | File Authorship | Directory Authorship|\n"); - fprintf(STDOUT, - " |----------|----------|----------|----------|\n"); - fprintf(STDOUT, - " | Same | Diff | Same | Diff |\n"); - fprintf(STDOUT, - " |----------|----------|----------|----------|\n"); - fprintf(STDOUT, "0-60 sec | %8d | %8d | %8d | %8d |\n", - a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_0], - a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_0], - a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_0], - a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_0]); - fprintf(STDOUT, "1-10 min | %8d | %8d | %8d | %8d |\n", - a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_1], - a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_1], - a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_1], - a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_1]); - fprintf(STDOUT, "10min-1hr | %8d | %8d | %8d | %8d |\n", - a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_2], - a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_2], - a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_2], - a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_2]); - fprintf(STDOUT, "1hr-1day | %8d | %8d | %8d | %8d |\n", - a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_3], - a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_3], - a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_3], - a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_3]); - fprintf(STDOUT, "1day-1wk | %8d | %8d | %8d | %8d |\n", - a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_4], - a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_4], - a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_4], - a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_4]); - fprintf(STDOUT, "> 1wk | %8d | %8d | %8d | %8d |\n", - a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_5], - a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_5], - a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_5], - a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_5]); - fprintf(STDOUT, - " |-------------------------------------------|\n"); - } /*Volume status OK */ - else if (a_xInfoP->status == VBUSY) { - (*a_totalBusyP)++; - qPut(&busyHead, a_xInfoP->volid); - if (a_showProblems) - fprintf(STDOUT, "**** Volume %lu is busy ****\n", - (unsigned long)a_xInfoP->volid); - } /*Busy volume */ - else { - (*a_totalNotOKP)++; - qPut(¬okHead, a_xInfoP->volid); - if (a_showProblems) - fprintf(STDOUT, "**** Could not attach volume %lu ****\n", - (unsigned long)a_xInfoP->volid); - } /*Screwed volume */ - fprintf(STDOUT, "\n"); - } /*Long listing */ - else { - /* - * Default listing. - */ - if (a_xInfoP->status == VOK) { - fprintf(STDOUT, "%-32s ", a_xInfoP->name); - fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid); - if (a_xInfoP->type == 0) - fprintf(STDOUT, "RW "); - if (a_xInfoP->type == 1) - fprintf(STDOUT, "RO "); - if (a_xInfoP->type == 2) - fprintf(STDOUT, "BK "); - fprintf(STDOUT, "%10d K ", a_xInfoP->size); - if (a_xInfoP->inUse == 1) { - fprintf(STDOUT, "On-line"); - (*a_totalOKP)++; - } else { - fprintf(STDOUT, "Off-line"); - (*a_totalNotOKP)++; - } - fprintf(STDOUT, "\n"); - } /*Volume OK */ - else if (a_xInfoP->status == VBUSY) { - (*a_totalBusyP)++; - qPut(&busyHead, a_xInfoP->volid); - if (a_showProblems) - fprintf(STDOUT, "**** Volume %lu is busy ****\n", - (unsigned long)a_xInfoP->volid); - } /*Busy volume */ - else { - (*a_totalNotOKP)++; - qPut(¬okHead, a_xInfoP->volid); - if (a_showProblems) - fprintf(STDOUT, "**** Could not attach volume %lu ****\n", - (unsigned long)a_xInfoP->volid); - } /*Screwed volume */ - } /*Default listing */ -} /*XDisplayFormat */ - -#ifdef FULL_LISTVOL_SWITCH -static void -DisplayFormat2(server, partition, pntr) - long server, partition; - volintInfo *pntr; -{ - static long server_cache = -1, partition_cache = -1; - static char hostname[256], address[32], pname[16]; - - if (server != server_cache) { - struct in_addr s; - - s.s_addr = server; - strcpy(hostname, hostutil_GetNameByINet(server)); - strcpy(address, inet_ntoa(s)); - server_cache = server; - } - if (partition != partition_cache) { - MapPartIdIntoName(partition, pname); - partition_cache = partition; - } else { - pname[0] = '\0'; - } - fprintf(STDOUT, "name\t\t%s\n", pntr->name); - fprintf(STDOUT, "id\t\t%lu\n", pntr->volid); - fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname); - fprintf(STDOUT, "part\t\t%s\n", pname); - switch (pntr->status) { - case VOK: - fprintf(STDOUT, "status\t\tOK\n"); - break; - case VBUSY: - fprintf(STDOUT, "status\t\tBUSY\n"); - return; - default: - fprintf(STDOUT, "status\t\tUNATTACHABLE\n"); - return; - } - fprintf(STDOUT, "backupID\t%lu\n", pntr->backupID); - fprintf(STDOUT, "parentID\t%lu\n", pntr->parentID); - fprintf(STDOUT, "cloneID\t\t%lu\n", pntr->cloneID); - fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N"); - fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N"); - /* 0xD3 is from afs/volume.h since I had trouble including the file */ - fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N"); - switch (pntr->type) { - case 0: - fprintf(STDOUT, "type\t\tRW\n"); - break; - case 1: - fprintf(STDOUT, "type\t\tRO\n"); - break; - case 2: - fprintf(STDOUT, "type\t\tBK\n"); - break; - default: - fprintf(STDOUT, "type\t\t?\n"); - break; - } - fprintf(STDOUT, "creationDate\t%-9lu\t%s", pntr->creationDate, - ctime(&pntr->creationDate)); - fprintf(STDOUT, "accessDate\t%-9lu\t%s", pntr->accessDate, - ctime(&pntr->accessDate)); - fprintf(STDOUT, "updateDate\t%-9lu\t%s", pntr->updateDate, - ctime(&pntr->updateDate)); - fprintf(STDOUT, "backupDate\t%-9lu\t%s", pntr->backupDate, - ctime(&pntr->backupDate)); - fprintf(STDOUT, "copyDate\t%-9lu\t%s", pntr->copyDate, - ctime(&pntr->copyDate)); - fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n", pntr->flags); - fprintf(STDOUT, "diskused\t%u\n", pntr->size); - fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota); - fprintf(STDOUT, "minquota\t%lu\t(Optional)\n", pntr->spare0); - fprintf(STDOUT, "filecount\t%u\n", pntr->filecount); - fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse); - fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1); - fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2); - fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3); - return; -} - -static void -DisplayVolumes2(server, partition, pntr, count) - volintInfo *pntr; - long server, partition, count; -{ - long i; - - for (i = 0; i < count; i++) { - fprintf(STDOUT, "BEGIN_OF_ENTRY\n"); - DisplayFormat2(server, partition, pntr); - fprintf(STDOUT, "END_OF_ENTRY\n\n"); - pntr++; - } - return; -} -#endif /* FULL_LISTVOL_SWITCH */ - -static void -DisplayVolumes(server, part, pntr, count, longlist, fast, quiet) - afs_int32 server, part; - volintInfo *pntr; - afs_int32 count, longlist, fast; - int quiet; -{ - int totalOK, totalNotOK, totalBusy, i; - afs_int32 volid; - - totalOK = 0; - totalNotOK = 0; - totalBusy = 0; - qInit(&busyHead); - qInit(¬okHead); - for (i = 0; i < count; i++) { - DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy, - fast, longlist, 0); - pntr++; - } - if (totalBusy) { - while (busyHead.count) { - qGet(&busyHead, &volid); - fprintf(STDOUT, "**** Volume %lu is busy ****\n", - (unsigned long)volid); - } - } - if (totalNotOK) { - while (notokHead.count) { - qGet(¬okHead, &volid); - fprintf(STDOUT, "**** Could not attach volume %lu ****\n", - (unsigned long)volid); - } - } - if (!quiet) { - fprintf(STDOUT, "\n"); - if (!fast) { - fprintf(STDOUT, - "Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n", - totalOK, totalNotOK, totalBusy); - } - } -} - -/*------------------------------------------------------------------------ - * PRIVATE XDisplayVolumes - * - * Description: - * Display extended volume information. - * - * Arguments: - * a_servID : Pointer to the Rx call we're performing. - * a_partID : Partition for which we want the extended list. - * a_xInfoP : Ptr to extended volume info. - * a_count : Number of volume records contained above. - * a_int32 : Int32 listing generated? - * a_fast : Fast listing generated? - * a_quiet : Quiet listing generated? - * - * Returns: - * Nothing. - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -static void -XDisplayVolumes(a_servID, a_partID, a_xInfoP, a_count, a_int32, a_fast, - a_quiet) - afs_int32 a_servID; - afs_int32 a_partID; - volintXInfo *a_xInfoP; - afs_int32 a_count; - afs_int32 a_int32; - afs_int32 a_fast; - int a_quiet; - -{ /*XDisplayVolumes */ - - int totalOK; /*Total OK volumes */ - int totalNotOK; /*Total screwed volumes */ - int totalBusy; /*Total busy volumes */ - int i; /*Loop variable */ - afs_int32 volid; /*Current volume ID */ - - /* - * Initialize counters and (global!!) queues. - */ - totalOK = 0; - totalNotOK = 0; - totalBusy = 0; - qInit(&busyHead); - qInit(¬okHead); - - /* - * Display each volume in the list. - */ - for (i = 0; i < a_count; i++) { - XDisplayFormat(a_xInfoP, a_servID, a_partID, &totalOK, &totalNotOK, - &totalBusy, a_fast, a_int32, 0); - a_xInfoP++; - } - - /* - * If any volumes were found to be busy or screwed, display them. - */ - if (totalBusy) { - while (busyHead.count) { - qGet(&busyHead, &volid); - fprintf(STDOUT, "**** Volume %lu is busy ****\n", - (unsigned long)volid); - } - } - if (totalNotOK) { - while (notokHead.count) { - qGet(¬okHead, &volid); - fprintf(STDOUT, "**** Could not attach volume %lu ****\n", - (unsigned long)volid); - } - } - - if (!a_quiet) { - fprintf(STDOUT, "\n"); - if (!a_fast) { - fprintf(STDOUT, - "Total volumes: %d on-line, %d off-line, %d busyd\n\n", - totalOK, totalNotOK, totalBusy); - } - } - -} /*XDisplayVolumes */ - -/* set and to the correct values depending on - * and */ -static void -GetServerAndPart(entry, voltype, server, part, previdx) - struct nvldbentry *entry; - afs_int32 *server, *part; - int voltype; - int *previdx; -{ - int i, istart, vtype; - - *server = -1; - *part = -1; - - /* Doesn't check for non-existance of backup volume */ - if ((voltype == RWVOL) || (voltype == BACKVOL)) { - vtype = ITSRWVOL; - istart = 0; /* seach the entire entry */ - } else { - vtype = ITSROVOL; - /* Seach from beginning of entry or pick up where we left off */ - istart = ((*previdx < 0) ? 0 : *previdx + 1); - } - - for (i = istart; i < entry->nServers; i++) { - if (entry->serverFlags[i] & vtype) { - *server = entry->serverNumber[i]; - *part = entry->serverPartition[i]; - *previdx = i; - return; - } - } - - /* Didn't find any, return -1 */ - *previdx = -1; - return; -} - -static void -PostVolumeStats(entry) - struct nvldbentry *entry; -{ - SubEnumerateEntry(entry); - /* Check for VLOP_ALLOPERS */ - if (entry->flags & VLOP_ALLOPERS) - fprintf(STDOUT, " Volume is currently LOCKED \n"); - return; -} - -/*------------------------------------------------------------------------ - * PRIVATE XVolumeStats - * - * Description: - * Display extended volume information. - * - * Arguments: - * a_xInfoP : Ptr to extended volume info. - * a_entryP : Ptr to the volume's VLDB entry. - * a_srvID : Server ID. - * a_partID : Partition ID. - * a_volType : Type of volume to print. - * - * Returns: - * Nothing. - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -static void -XVolumeStats(a_xInfoP, a_entryP, a_srvID, a_partID, a_volType) - volintXInfo *a_xInfoP; - struct nvldbentry *a_entryP; - afs_int32 a_srvID; - afs_int32 a_partID; - int a_volType; - -{ /*XVolumeStats */ - - int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here */ - - XDisplayFormat(a_xInfoP, /*Ptr to extended volume info */ - a_srvID, /*Server ID to print */ - a_partID, /*Partition ID to print */ - &totalOK, /*Ptr to total-OK counter */ - &totalNotOK, /*Ptr to total-screwed counter */ - &totalBusy, /*Ptr to total-busy counter */ - 0, /*Don't do a fast listing */ - 1, /*Do a long listing */ - 1); /*Show volume problems */ - return; - -} /*XVolumeStats */ - -static void -VolumeStats(pntr, entry, server, part, voltype) - volintInfo *pntr; - struct nvldbentry *entry; - int voltype; - afs_int32 server, part; -{ - int totalOK, totalNotOK, totalBusy; - - DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy, 0, 1, - 1); - return; -} - -/* command to forcibly remove a volume */ -static -NukeVolume(as) - register struct cmd_syndesc *as; -{ - register afs_int32 code; - afs_int32 volID, err; - afs_int32 partID; - afs_int32 server; - register char *tp; - - server = GetServer(tp = as->parms[0].items->data); - if (!server) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", tp); - return 1; - } - - partID = volutil_GetPartitionID(tp = as->parms[1].items->data); - if (partID == -1) { - fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp); - return 1; - } - - volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err); - if (volID == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, - "vos: could not parse '%s' as a numeric volume ID", tp); - return 1; - } - - fprintf(STDOUT, - "vos: forcibly removing all traces of volume %d, please wait...", - volID); - fflush(STDOUT); - code = UV_NukeVolume(server, partID, volID); - if (code == 0) - fprintf(STDOUT, "done.\n"); - else - fprintf(STDOUT, "failed with code %d.\n", code); - return code; -} - - -/*------------------------------------------------------------------------ - * PRIVATE ExamineVolume - * - * Description: - * Routine used to examine a single volume, contacting the VLDB as - * well as the Volume Server. - * - * Arguments: - * as : Ptr to parsed command line arguments. - * - * Returns: - * 0 for a successful operation, - * Otherwise, one of the ubik or VolServer error values. - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------ - */ -static -ExamineVolume(as) - register struct cmd_syndesc *as; -{ - struct nvldbentry entry; - afs_int32 vcode = 0; - volintInfo *pntr = (volintInfo *) 0; - volintXInfo *xInfoP = (volintXInfo *) 0; - afs_int32 volid; - afs_int32 code, err, error = 0; - int voltype, foundserv = 0, foundentry = 0; - afs_int32 aserver, apart; - int previdx = -1; - int wantExtendedInfo; /*Do we want extended vol info? */ - - wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */ - - volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */ - if (volid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "Unknown volume ID or name '%s'\n", - as->parms[0].items->data); - return -1; - } - - if (verbose) { - fprintf(STDOUT, "Fetching VLDB entry for %lu .. ", - (unsigned long)volid); - fflush(STDOUT); - } - vcode = VLDB_GetEntryByID(volid, -1, &entry); - if (vcode) { - fprintf(STDERR, - "Could not fetch the entry for volume number %lu from VLDB \n", - (unsigned long)volid); - return (vcode); - } - if (verbose) - fprintf(STDOUT, "done\n"); - MapHostToNetwork(&entry); - - if (entry.volumeId[RWVOL] == volid) - voltype = RWVOL; - else if (entry.volumeId[BACKVOL] == volid) - voltype = BACKVOL; - else /* (entry.volumeId[ROVOL] == volid) */ - voltype = ROVOL; - - do { /* do {...} while (voltype == ROVOL) */ - /* Get the entry for the volume. If its a RW vol, get the RW entry. - * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist). - * If its a RO vol, get the next RO entry. - */ - GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL), - &aserver, &apart, &previdx); - if (previdx == -1) { /* searched all entries */ - if (!foundentry) { - fprintf(STDERR, "Volume %s does not exist in VLDB\n\n", - as->parms[0].items->data); - error = ENOENT; - } - break; - } - foundentry = 1; - - /* Get information about the volume from the server */ - if (verbose) { - fprintf(STDOUT, "Getting volume listing from the server %s .. ", - hostutil_GetNameByINet(aserver)); - fflush(STDOUT); - } - if (wantExtendedInfo) - code = UV_XListOneVolume(aserver, apart, volid, &xInfoP); - else - code = UV_ListOneVolume(aserver, apart, volid, &pntr); - if (verbose) - fprintf(STDOUT, "done\n"); - - if (code) { - error = code; - if (code == ENODEV) { - if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) { - /* The VLDB says there is no backup volume and its not on disk */ - fprintf(STDERR, "Volume %s does not exist\n", - as->parms[0].items->data); - error = ENOENT; - } else { - fprintf(STDERR, - "Volume does not exist on server %s as indicated by the VLDB\n", - hostutil_GetNameByINet(aserver)); - } - } else { - PrintDiagnostics("examine", code); - } - fprintf(STDOUT, "\n"); - } else { - foundserv = 1; - if (wantExtendedInfo) - XVolumeStats(xInfoP, &entry, aserver, apart, voltype); - else -#ifdef FULL_LISTVOL_SWITCH - if (as->parms[2].items) { - DisplayFormat2(aserver, apart, pntr); - EnumerateEntry(&entry); - } else -#endif /* FULL_LISTVOL_SWITCH */ - VolumeStats(pntr, &entry, aserver, apart, voltype); - - if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) { - /* The VLDB says there is no backup volume yet we found one on disk */ - fprintf(STDERR, "Volume %s does not exist in VLDB\n", - as->parms[0].items->data); - error = ENOENT; - } - } - - if (pntr) - free(pntr); - if (xInfoP) - free(xInfoP); - } while (voltype == ROVOL); - - if (!foundserv) { - fprintf(STDERR, "Dump only information from VLDB\n\n"); - fprintf(STDOUT, "%s \n", entry.name); /* PostVolumeStats doesn't print name */ - } - PostVolumeStats(&entry); - - return (error); -} - -/*------------------------------------------------------------------------ - * PRIVATE SetFields - * - * Description: - * Routine used to change the status of a single volume. - * - * Arguments: - * as : Ptr to parsed command line arguments. - * - * Returns: - * 0 for a successful operation, - * Otherwise, one of the ubik or VolServer error values. - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------ - */ -static -SetFields(as) - register struct cmd_syndesc *as; -{ - struct nvldbentry entry; - afs_int32 vcode = 0; - volintInfo info; - afs_int32 volid; - afs_int32 code, err; - afs_int32 aserver, apart; - int previdx = -1; - - volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */ - if (volid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "Unknown volume ID or name '%s'\n", - as->parms[0].items->data); - return -1; - } - - code = VLDB_GetEntryByID(volid, RWVOL, &entry); - if (code) { - fprintf(STDERR, - "Could not fetch the entry for volume number %lu from VLDB \n", - (unsigned long)volid); - return (code); - } - MapHostToNetwork(&entry); - - GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx); - if (previdx == -1) { - fprintf(STDERR, "Volume %s does not exist in VLDB\n\n", - as->parms[0].items->data); - return (ENOENT); - } - - memset(&info, 0, sizeof(info)); - info.volid = volid; - info.type = RWVOL; - info.dayUse = -1; - info.maxquota = -1; - info.flags = -1; - info.spare0 = -1; - info.spare1 = -1; - info.spare2 = -1; - info.spare3 = -1; - - if (as->parms[1].items) { - /* -max */ - code = util_GetInt32(as->parms[1].items->data, &info.maxquota); - if (code) { - fprintf(STDERR, "invalid quota value\n"); - return code; - } - } - if (as->parms[2].items) { - /* -clearuse */ - info.dayUse = 0; - } - code = UV_SetVolumeInfo(aserver, apart, volid, &info); - if (code) - fprintf(STDERR, - "Could not update volume info fields for volume number %lu\n", - (unsigned long)volid); - return (code); -} - -/*------------------------------------------------------------------------ - * PRIVATE volOnline - * - * Description: - * Brings a volume online. - * - * Arguments: - * as : Ptr to parsed command line arguments. - * - * Returns: - * 0 for a successful operation, - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------ - */ -static -volOnline(as) - register struct cmd_syndesc *as; -{ - afs_int32 server, partition, volid; - afs_int32 code, err = 0; - - server = GetServer(as->parms[0].items->data); - if (server == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - return -1; - } - - partition = volutil_GetPartitionID(as->parms[1].items->data); - if (partition < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - return ENOENT; - } - - volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */ - if (!volid) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "Unknown volume ID or name '%s'\n", - as->parms[0].items->data); - return -1; - } - - code = UV_SetVolume(server, partition, volid, ITOffline, 0 /*online */ , - 0 /*sleep */ ); - if (code) { - fprintf(STDERR, "Failed to set volume. Code = %d\n", code); - return -1; - } - - return 0; -} - -/*------------------------------------------------------------------------ - * PRIVATE volOffline - * - * Description: - * Brings a volume offline. - * - * Arguments: - * as : Ptr to parsed command line arguments. - * - * Returns: - * 0 for a successful operation, - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------ - */ -static int -volOffline(register struct cmd_syndesc *as) -{ - afs_int32 server, partition, volid; - afs_int32 code, err = 0; - afs_int32 transflag, sleeptime, transdone; - - server = GetServer(as->parms[0].items->data); - if (server == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - return -1; - } - - partition = volutil_GetPartitionID(as->parms[1].items->data); - if (partition < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - return ENOENT; - } - - volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */ - if (!volid) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "Unknown volume ID or name '%s'\n", - as->parms[0].items->data); - return -1; - } - - transflag = (as->parms[4].items ? ITBusy : ITOffline); - sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0); - transdone = (sleeptime ? 0 /*online */ : VTOutOfService); - if (as->parms[4].items && !as->parms[3].items) { - fprintf(STDERR, "-sleep option must be used with -busy flag\n"); - return -1; - } - - code = - UV_SetVolume(server, partition, volid, transflag, transdone, - sleeptime); - if (code) { - fprintf(STDERR, "Failed to set volume. Code = %d\n", code); - return -1; - } - - return 0; -} - -static int -CreateVolume(register struct cmd_syndesc *as) -{ - afs_int32 pnum; - char part[10]; - afs_int32 volid, code; - struct nvldbentry entry; - afs_int32 vcode; - afs_int32 quota; - - quota = 5000; - tserver = GetServer(as->parms[0].items->data); - if (!tserver) { - fprintf(STDERR, "vos: host '%s' not found in host table\n", - as->parms[0].items->data); - return ENOENT; - } - pnum = volutil_GetPartitionID(as->parms[1].items->data); - if (pnum < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - return ENOENT; - } - if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - return ENOENT; - } - if (!ISNAMEVALID(as->parms[2].items->data)) { - fprintf(STDERR, - "vos: the name of the root volume %s exceeds the size limit of %d\n", - as->parms[2].items->data, VOLSER_OLDMAXVOLNAME - 10); - return E2BIG; - } - if (!VolNameOK(as->parms[2].items->data)) { - fprintf(STDERR, - "Illegal volume name %s, should not end in .readonly or .backup\n", - as->parms[2].items->data); - return EINVAL; - } - if (IsNumeric(as->parms[2].items->data)) { - fprintf(STDERR, "Illegal volume name %s, should not be a number\n", - as->parms[2].items->data); - return EINVAL; - } - vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry); - if (!vcode) { - fprintf(STDERR, "Volume %s already exists\n", - as->parms[2].items->data); - PrintDiagnostics("create", code); - return EEXIST; - } - - if (as->parms[3].items) { - if (!IsNumeric(as->parms[3].items->data)) { - fprintf(STDERR, "Initial quota %s should be numeric.\n", - as->parms[3].items->data); - return EINVAL; - } - - code = util_GetInt32(as->parms[3].items->data, "a); - if (code) { - fprintf(STDERR, "vos: bad integer specified for quota.\n"); - return code; - } - } - - code = - UV_CreateVolume2(tserver, pnum, as->parms[2].items->data, quota, 0, - 0, 0, 0, &volid); - if (code) { - PrintDiagnostics("create", code); - return code; - } - MapPartIdIntoName(pnum, part); - fprintf(STDOUT, "Volume %lu created on partition %s of %s\n", - (unsigned long)volid, part, as->parms[0].items->data); - - return 0; -} - -static afs_int32 -DeleteAll(entry) - struct nvldbentry *entry; -{ - int i; - afs_int32 error, code, curserver, curpart, volid; - - MapHostToNetwork(entry); - error = 0; - for (i = 0; i < entry->nServers; i++) { - curserver = entry->serverNumber[i]; - curpart = entry->serverPartition[i]; - if (entry->serverFlags[i] & ITSROVOL) { - volid = entry->volumeId[ROVOL]; - } else { - volid = entry->volumeId[RWVOL]; - } - code = UV_DeleteVolume(curserver, curpart, volid); - if (code && !error) - error = code; - } - return error; -} - -static -DeleteVolume(as) - struct cmd_syndesc *as; -{ - afs_int32 err, code = 0; - afs_int32 server = 0, partition = -1, volid; - char pname[10]; - afs_int32 idx, j; - - if (as->parms[0].items) { - server = GetServer(as->parms[0].items->data); - if (!server) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - return ENOENT; - } - } - - if (as->parms[1].items) { - partition = volutil_GetPartitionID(as->parms[1].items->data); - if (partition < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - return EINVAL; - } - - /* Check for validity of the partition */ - if (!IsPartValid(partition, server, &code)) { - if (code) { - PrintError("", code); - } else { - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - } - return ENOENT; - } - } - - volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); - if (volid == 0) { - fprintf(STDERR, "Can't find volume name '%s' in VLDB\n", - as->parms[2].items->data); - if (err) - PrintError("", err); - return ENOENT; - } - - /* If the server or partition option are not complete, try to fill - * them in from the VLDB entry. - */ - if ((partition == -1) || !server) { - struct nvldbentry entry; - - code = VLDB_GetEntryByID(volid, -1, &entry); - if (code) { - fprintf(STDERR, - "Could not fetch the entry for volume %lu from VLDB\n", - (unsigned long)volid); - PrintError("", code); - return (code); - } - - if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS)) - || ((volid == entry.volumeId[BACKVOL]) - && (entry.flags & BACK_EXISTS))) { - idx = Lp_GetRwIndex(&entry); - if ((idx == -1) || (server && (server != entry.serverNumber[idx])) - || ((partition != -1) - && (partition != entry.serverPartition[idx]))) { - fprintf(STDERR, "VLDB: Volume '%s' no match\n", - as->parms[2].items->data); - return ENOENT; - } - } else if ((volid == entry.volumeId[ROVOL]) - && (entry.flags & RO_EXISTS)) { - for (idx = -1, j = 0; j < entry.nServers; j++) { - if (entry.serverFlags[j] != ITSROVOL) - continue; - - if (((server == 0) || (server == entry.serverNumber[j])) - && ((partition == -1) - || (partition == entry.serverPartition[j]))) { - if (idx != -1) { - fprintf(STDERR, - "VLDB: Volume '%s' matches more than one RO\n", - as->parms[2].items->data); - return ENOENT; - } - idx = j; - } - } - if (idx == -1) { - fprintf(STDERR, "VLDB: Volume '%s' no match\n", - as->parms[2].items->data); - return ENOENT; - } - } else { - fprintf(STDERR, "VLDB: Volume '%s' no match\n", - as->parms[2].items->data); - return ENOENT; - } - - server = htonl(entry.serverNumber[idx]); - partition = entry.serverPartition[idx]; - } - - - code = UV_DeleteVolume(server, partition, volid); - if (code) { - PrintDiagnostics("remove", code); - return code; - } - - MapPartIdIntoName(partition, pname); - fprintf(STDOUT, "Volume %lu on partition %s server %s deleted\n", - (unsigned long)volid, pname, hostutil_GetNameByINet(server)); - return 0; -} - -#define TESTM 0 /* set for move space tests, clear for production */ -static -MoveVolume(as) - register struct cmd_syndesc *as; -{ - - afs_int32 volid, fromserver, toserver, frompart, topart; - afs_int32 flags, code, err; - char fromPartName[10], toPartName[10]; - - struct diskPartition partition; /* for space check */ - volintInfo *p; - - volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); - if (volid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume ID or name '%s'\n", - as->parms[0].items->data); - return ENOENT; - } - fromserver = GetServer(as->parms[1].items->data); - if (fromserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[1].items->data); - return ENOENT; - } - toserver = GetServer(as->parms[3].items->data); - if (toserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[3].items->data); - return ENOENT; - } - frompart = volutil_GetPartitionID(as->parms[2].items->data); - if (frompart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[2].items->data); - return EINVAL; - } - if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[2].items->data); - return ENOENT; - } - topart = volutil_GetPartitionID(as->parms[4].items->data); - if (topart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[4].items->data); - return EINVAL; - } - if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[4].items->data); - return ENOENT; - } - - flags = 0; - if (as->parms[5].items) flags |= RV_NOCLONE; - - /* - * check source partition for space to clone volume - */ - - MapPartIdIntoName(topart, toPartName); - MapPartIdIntoName(frompart, fromPartName); - - /* - * check target partition for space to move volume - */ - - code = UV_PartitionInfo(toserver, toPartName, &partition); - if (code) { - fprintf(STDERR, "vos: cannot access partition %s\n", toPartName); - exit(1); - } - if (TESTM) - fprintf(STDOUT, "target partition %s free space %d\n", toPartName, - partition.free); - - p = (volintInfo *) 0; - code = UV_ListOneVolume(fromserver, frompart, volid, &p); - if (code) { - fprintf(STDERR, "vos:cannot access volume %lu\n", - (unsigned long)volid); - free(p); - exit(1); - } - if (TESTM) - fprintf(STDOUT, "volume %lu size %d\n", (unsigned long)volid, - p->size); - if (partition.free <= p->size) { - fprintf(STDERR, - "vos: no space on target partition %s to move volume %lu\n", - toPartName, (unsigned long)volid); - free(p); - exit(1); - } - free(p); - - if (TESTM) { - fprintf(STDOUT, "size test - don't do move\n"); - exit(0); - } - - /* successful move still not guaranteed but shoot for it */ - - code = - UV_MoveVolume2(volid, fromserver, frompart, toserver, topart, flags); - if (code) { - PrintDiagnostics("move", code); - return code; - } - MapPartIdIntoName(topart, toPartName); - MapPartIdIntoName(frompart, fromPartName); - fprintf(STDOUT, "Volume %lu moved from %s %s to %s %s \n", - (unsigned long)volid, as->parms[1].items->data, fromPartName, - as->parms[3].items->data, toPartName); - - return 0; -} - -static -CopyVolume(as) - register struct cmd_syndesc *as; -{ - afs_int32 volid, fromserver, toserver, frompart, topart, code, err, flags; - char fromPartName[10], toPartName[10], *tovolume; - struct nvldbentry entry; - struct diskPartition partition; /* for space check */ - volintInfo *p; - - volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); - if (volid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume ID or name '%s'\n", - as->parms[0].items->data); - return ENOENT; - } - fromserver = GetServer(as->parms[1].items->data); - if (fromserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[1].items->data); - return ENOENT; - } - - toserver = GetServer(as->parms[4].items->data); - if (toserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[4].items->data); - return ENOENT; - } - - tovolume = as->parms[3].items->data; - if (!ISNAMEVALID(tovolume)) { - fprintf(STDERR, - "vos: the name of the root volume %s exceeds the size limit of %d\n", - tovolume, VOLSER_OLDMAXVOLNAME - 10); - return E2BIG; - } - if (!VolNameOK(tovolume)) { - fprintf(STDERR, - "Illegal volume name %s, should not end in .readonly or .backup\n", - tovolume); - return EINVAL; - } - if (IsNumeric(tovolume)) { - fprintf(STDERR, "Illegal volume name %s, should not be a number\n", - tovolume); - return EINVAL; - } - code = VLDB_GetEntryByName(tovolume, &entry); - if (!code) { - fprintf(STDERR, "Volume %s already exists\n", tovolume); - PrintDiagnostics("copy", code); - return EEXIST; - } - - frompart = volutil_GetPartitionID(as->parms[2].items->data); - if (frompart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[2].items->data); - return EINVAL; - } - if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[2].items->data); - return ENOENT; - } - - topart = volutil_GetPartitionID(as->parms[5].items->data); - if (topart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[5].items->data); - return EINVAL; - } - if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[5].items->data); - return ENOENT; - } - - flags = 0; - if (as->parms[6].items) flags |= RV_OFFLINE; - if (as->parms[7].items) flags |= RV_RDONLY; - if (as->parms[8].items) flags |= RV_NOCLONE; - - MapPartIdIntoName(topart, toPartName); - MapPartIdIntoName(frompart, fromPartName); - - /* - * check target partition for space to move volume - */ - - code = UV_PartitionInfo(toserver, toPartName, &partition); - if (code) { - fprintf(STDERR, "vos: cannot access partition %s\n", toPartName); - exit(1); - } - if (TESTM) - fprintf(STDOUT, "target partition %s free space %d\n", toPartName, - partition.free); - - p = (volintInfo *) 0; - code = UV_ListOneVolume(fromserver, frompart, volid, &p); - if (code) { - fprintf(STDERR, "vos:cannot access volume %lu\n", - (unsigned long)volid); - free(p); - exit(1); - } - - if (partition.free <= p->size) { - fprintf(STDERR, - "vos: no space on target partition %s to copy volume %lu\n", - toPartName, (unsigned long)volid); - free(p); - exit(1); - } - free(p); - - /* successful copy still not guaranteed but shoot for it */ - - code = - UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver, - topart, 0, flags); - if (code) { - PrintDiagnostics("copy", code); - return code; - } - MapPartIdIntoName(topart, toPartName); - MapPartIdIntoName(frompart, fromPartName); - fprintf(STDOUT, "Volume %lu copied from %s %s to %s on %s %s \n", - (unsigned long)volid, as->parms[1].items->data, fromPartName, - tovolume, as->parms[4].items->data, toPartName); - - return 0; -} - - -static -ShadowVolume(as) - register struct cmd_syndesc *as; -{ - afs_int32 volid, fromserver, toserver, frompart, topart, tovolid; - afs_int32 code, err, flags; - char fromPartName[10], toPartName[10], toVolName[32], *tovolume; - struct nvldbentry entry; - struct diskPartition partition; /* for space check */ - volintInfo *p, *q; - - p = (volintInfo *) 0; - q = (volintInfo *) 0; - - volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); - if (volid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume ID or name '%s'\n", - as->parms[0].items->data); - return ENOENT; - } - fromserver = GetServer(as->parms[1].items->data); - if (fromserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[1].items->data); - return ENOENT; - } - - toserver = GetServer(as->parms[3].items->data); - if (toserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[3].items->data); - return ENOENT; - } - - frompart = volutil_GetPartitionID(as->parms[2].items->data); - if (frompart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[2].items->data); - return EINVAL; - } - if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[2].items->data); - return ENOENT; - } - - topart = volutil_GetPartitionID(as->parms[4].items->data); - if (topart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[4].items->data); - return EINVAL; - } - if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[4].items->data); - return ENOENT; - } - - if (as->parms[5].items) { - tovolume = as->parms[5].items->data; - if (!ISNAMEVALID(tovolume)) { - fprintf(STDERR, - "vos: the name of the root volume %s exceeds the size limit of %d\n", - tovolume, VOLSER_OLDMAXVOLNAME - 10); - return E2BIG; - } - if (!VolNameOK(tovolume)) { - fprintf(STDERR, - "Illegal volume name %s, should not end in .readonly or .backup\n", - tovolume); - return EINVAL; - } - if (IsNumeric(tovolume)) { - fprintf(STDERR, - "Illegal volume name %s, should not be a number\n", - tovolume); - return EINVAL; - } - } else { - /* use actual name of source volume */ - code = UV_ListOneVolume(fromserver, frompart, volid, &p); - if (code) { - fprintf(STDERR, "vos:cannot access volume %lu\n", - (unsigned long)volid); - exit(1); - } - strcpy(toVolName, p->name); - tovolume = toVolName; - /* save p for size checks later */ - } - - if (as->parms[6].items) { - tovolid = vsu_GetVolumeID(as->parms[6].items->data, cstruct, &err); - if (tovolid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume ID or name '%s'\n", - as->parms[6].items->data); - if (p) - free(p); - return ENOENT; - } - } else { - tovolid = vsu_GetVolumeID(tovolume, cstruct, &err); - if (tovolid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume ID or name '%s'\n", - tovolume); - if (p) - free(p); - return ENOENT; - } - } - - flags = RV_NOVLDB; - if (as->parms[7].items) flags |= RV_OFFLINE; - if (as->parms[8].items) flags |= RV_RDONLY; - if (as->parms[9].items) flags |= RV_NOCLONE; - if (as->parms[10].items) flags |= RV_CPINCR; - - MapPartIdIntoName(topart, toPartName); - MapPartIdIntoName(frompart, fromPartName); - - /* - * check target partition for space to move volume - */ - - code = UV_PartitionInfo(toserver, toPartName, &partition); - if (code) { - fprintf(STDERR, "vos: cannot access partition %s\n", toPartName); - exit(1); - } - if (TESTM) - fprintf(STDOUT, "target partition %s free space %d\n", toPartName, - partition.free); - - /* Don't do this again if we did it above */ - if (!p) { - code = UV_ListOneVolume(fromserver, frompart, volid, &p); - if (code) { - fprintf(STDERR, "vos:cannot access volume %lu\n", - (unsigned long)volid); - exit(1); - } - } - - /* OK if this fails */ - code = UV_ListOneVolume(toserver, topart, tovolid, &q); - - /* Treat existing volume size as "free" */ - if (q) - p->size = (q->size < p->size) ? p->size - q->size : 0; - - if (partition.free <= p->size) { - fprintf(STDERR, - "vos: no space on target partition %s to copy volume %lu\n", - toPartName, (unsigned long)volid); - free(p); - if (q) free(q); - exit(1); - } - free(p); - if (q) free(q); - - /* successful copy still not guaranteed but shoot for it */ - - code = - UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver, - topart, tovolid, flags); - if (code) { - PrintDiagnostics("shadow", code); - return code; - } - MapPartIdIntoName(topart, toPartName); - MapPartIdIntoName(frompart, fromPartName); - fprintf(STDOUT, "Volume %lu shadowed from %s %s to %s %s \n", - (unsigned long)volid, as->parms[1].items->data, fromPartName, - as->parms[4].items->data, toPartName); - - return 0; -} - - -static -CloneVolume(as) - register struct cmd_syndesc *as; -{ - afs_int32 server, part, volid, cloneid, voltype; - char partName[10], *volname; - afs_int32 code, err, flags; - struct nvldbentry entry; - - volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); - if (volid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume ID or name '%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; - } - server = GetServer(as->parms[1].items->data); - if (server == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[1].items->data); - return ENOENT; - } - part = volutil_GetPartitionID(as->parms[2].items->data); - if (part < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[2].items->data); - return EINVAL; - } - if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[2].items->data); - return ENOENT; - } - } else { - code = GetVolumeInfo(volid, &server, &part, &voltype, &entry); - if (code) - return code; - } - - volname = 0; - if (as->parms[3].items) { - volname = as->parms[3].items->data; - if (strlen(volname) > VOLSER_OLDMAXVOLNAME - 1) { - fprintf(STDERR, - "vos: the name of the root volume %s exceeds the size limit of %d\n", - volname, VOLSER_OLDMAXVOLNAME - 1); - return E2BIG; - } - if (!VolNameOK(volname)) { - fprintf(STDERR, - "Illegal volume name %s, should not end in .readonly or .backup\n", - volname); - return EINVAL; - } - if (IsNumeric(volname)) { - fprintf(STDERR, - "Illegal volume name %s, should not be a number\n", - volname); - return EINVAL; - } - } - - cloneid = 0; - if (as->parms[4].items) { - cloneid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err); - if (cloneid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume ID or name '%s'\n", - as->parms[4].items->data); - return ENOENT; - } - } - - flags = 0; - if (as->parms[5].items) flags |= RV_OFFLINE; - if (as->parms[6].items) flags |= RV_RDONLY; - - - code = - UV_CloneVolume(server, part, volid, cloneid, volname, flags); - - if (code) { - PrintDiagnostics("clone", code); - return code; - } - MapPartIdIntoName(part, partName); - fprintf(STDOUT, "Created clone for volume %lu\n", - as->parms[0].items->data); - - return 0; -} - - -static -BackupVolume(as) - register struct cmd_syndesc *as; -{ - afs_int32 avolid, aserver, apart, vtype, code, err; - struct nvldbentry entry; - - afs_int32 buvolid, buserver, bupart, butype; - struct nvldbentry buentry; - - 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 ID or name '%s'\n", - as->parms[0].items->data); - return ENOENT; - } - code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry); - if (code) - exit(1); - - /* verify this is a readwrite volume */ - - if (vtype != RWVOL) { - fprintf(STDERR, "%s not RW volume\n", as->parms[0].items->data); - exit(1); - } - - /* is there a backup volume already? */ - - if (entry.flags & BACK_EXISTS) { - /* yep, where is it? */ - - buvolid = entry.volumeId[BACKVOL]; - code = GetVolumeInfo(buvolid, &buserver, &bupart, &butype, &buentry); - if (code) - exit(1); - - /* is it local? */ - code = VLDB_IsSameAddrs(buserver, aserver, &err); - if (err) { - fprintf(STDERR, - "Failed to get info about server's %d address(es) from vlserver; aborting call!\n", - buserver); - exit(1); - } - if (!code) { - fprintf(STDERR, - "FATAL ERROR: backup volume %lu exists on server %lu\n", - (unsigned long)buvolid, (unsigned long)buserver); - exit(1); - } - } - - /* nope, carry on */ - - code = UV_BackupVolume(aserver, apart, avolid); - - if (code) { - PrintDiagnostics("backup", code); - return code; - } - fprintf(STDOUT, "Created backup volume for %s \n", - as->parms[0].items->data); - return 0; -} - -static -ReleaseVolume(as) - register struct cmd_syndesc *as; -{ - - struct nvldbentry entry; - afs_int32 avolid, aserver, apart, vtype, code, err; - int force = 0; - - if (as->parms[1].items) - force = 1; - 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; - } - code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry); - if (code) - return code; - - if (vtype != RWVOL) { - fprintf(STDERR, "%s not a RW volume\n", as->parms[0].items->data); - return (ENOENT); - } - - if (!ISNAMEVALID(entry.name)) { - fprintf(STDERR, - "Volume name %s is too long, rename before releasing\n", - entry.name); - return E2BIG; - } - - code = UV_ReleaseVolume(avolid, aserver, apart, force); - if (code) { - PrintDiagnostics("release", code); - return code; - } - fprintf(STDOUT, "Released volume %s successfully\n", - as->parms[0].items->data); - return 0; -} - -static -DumpVolume(as) - register struct cmd_syndesc *as; - -{ - afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i; - char filename[NameLen]; - struct nvldbentry entry; - - 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[3].items || as->parms[4].items) { - if (!as->parms[3].items || !as->parms[4].items) { - fprintf(STDERR, - "Must specify both -server and -partition options\n"); - return -1; - } - aserver = GetServer(as->parms[3].items->data); - if (aserver == 0) { - fprintf(STDERR, "Invalid server name\n"); - return -1; - } - apart = volutil_GetPartitionID(as->parms[4].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; - } - - if (as->parms[1].items && strcmp(as->parms[1].items->data, "0")) { - code = ktime_DateToInt32(as->parms[1].items->data, &fromdate); - if (code) { - fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n", - as->parms[1].items->data, code); - return code; - } - } - if (as->parms[2].items) { - strcpy(filename, as->parms[2].items->data); - } else { - strcpy(filename, ""); - } - - if (as->parms[5].items) { - code = - UV_DumpClonedVolume(avolid, aserver, apart, fromdate, - DumpFunction, filename); - } else { - code = - UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction, - filename); - } - if (code) { - PrintDiagnostics("dump", code); - return code; - } - if (strcmp(filename, "")) - fprintf(STDERR, "Dumped volume %s in file %s\n", - as->parms[0].items->data, filename); - else - fprintf(STDERR, "Dumped volume %s in stdout \n", - as->parms[0].items->data); - return 0; -} - -#define ASK 0 -#define ABORT 1 -#define FULL 2 -#define INC 3 - -static -RestoreVolume(as) - register struct cmd_syndesc *as; - -{ - afs_int32 avolid, aserver, apart, code, vcode, err; - afs_int32 aoverwrite = ASK; - int restoreflags, readonly = 0, offline = 0, voltype = RWVOL; - char prompt; - char afilename[NameLen], avolname[VOLSER_MAXVOLNAME + 1], apartName[10]; - char volname[VOLSER_MAXVOLNAME + 1]; - struct nvldbentry entry; - - prompt = 'n'; - - if (as->parms[4].items) { - avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err); - if (avolid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume '%s'\n", - as->parms[4].items->data); - exit(1); - } - } else - avolid = 0; - - if (as->parms[5].items) { - if ((strcmp(as->parms[5].items->data, "a") == 0) - || (strcmp(as->parms[5].items->data, "abort") == 0)) { - aoverwrite = ABORT; - } else if ((strcmp(as->parms[5].items->data, "f") == 0) - || (strcmp(as->parms[5].items->data, "full") == 0)) { - aoverwrite = FULL; - } else if ((strcmp(as->parms[5].items->data, "i") == 0) - || (strcmp(as->parms[5].items->data, "inc") == 0) - || (strcmp(as->parms[5].items->data, "increment") == 0) - || (strcmp(as->parms[5].items->data, "incremental") == 0)) { - aoverwrite = INC; - } else { - fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n", - as->parms[5].items->data); - exit(1); - } - } - if (as->parms[6].items) - offline = 1; - if (as->parms[7].items) { - readonly = 1; - voltype = ROVOL; - } - - aserver = GetServer(as->parms[0].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - apart = volutil_GetPartitionID(as->parms[1].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } - if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - exit(1); - } - strcpy(avolname, as->parms[2].items->data); - if (!ISNAMEVALID(avolname)) { - fprintf(STDERR, - "vos: the name of the volume %s exceeds the size limit\n", - avolname); - exit(1); - } - if (!VolNameOK(avolname)) { - fprintf(STDERR, - "Illegal volume name %s, should not end in .readonly or .backup\n", - avolname); - exit(1); - } - if (as->parms[3].items) { - strcpy(afilename, as->parms[3].items->data); - if (!FileExists(afilename)) { - fprintf(STDERR, "Can't access file %s\n", afilename); - exit(1); - } - } else { - strcpy(afilename, ""); - } - - /* Check if volume exists or not */ - - vsu_ExtractName(volname, avolname); - vcode = VLDB_GetEntryByName(volname, &entry); - if (vcode) { /* no volume - do a full restore */ - restoreflags = RV_FULLRST; - if ((aoverwrite == INC) || (aoverwrite == ABORT)) - fprintf(STDERR, - "Volume does not exist; Will perform a full restore\n"); - } - - else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */ - ||(readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */ - restoreflags = RV_FULLRST; - if ((aoverwrite == INC) || (aoverwrite == ABORT)) - fprintf(STDERR, - "%s Volume does not exist; Will perform a full restore\n", - readonly ? "RO" : "RW"); - - if (avolid == 0) { - avolid = entry.volumeId[voltype]; - } else if (entry.volumeId[voltype] != 0 - && entry.volumeId[voltype] != avolid) { - avolid = entry.volumeId[voltype]; - } - } - - else { /* volume exists - do we do a full incremental or abort */ - int Oserver, Opart, Otype, vol_elsewhere = 0; - struct nvldbentry Oentry; - int c, dc; - - if (avolid == 0) { - avolid = entry.volumeId[voltype]; - } else if (entry.volumeId[voltype] != 0 - && entry.volumeId[voltype] != avolid) { - avolid = entry.volumeId[voltype]; - } - - /* A file name was specified - check if volume is on another partition */ - vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry); - if (vcode) - exit(1); - - vcode = VLDB_IsSameAddrs(Oserver, aserver, &err); - if (err) { - fprintf(STDERR, - "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n", - Oserver, err); - exit(1); - } - if (!vcode || (Opart != apart)) - vol_elsewhere = 1; - - if (aoverwrite == ASK) { - if (strcmp(afilename, "") == 0) { /* The file is from standard in */ - fprintf(STDERR, - "Volume exists and no -overwrite option specified; Aborting restore command\n"); - exit(1); - } - - /* Ask what to do */ - if (vol_elsewhere) { - fprintf(STDERR, - "The volume %s %u already exists on a different server/part\n", - volname, entry.volumeId[voltype]); - fprintf(STDERR, - "Do you want to do a full restore or abort? [fa](a): "); - } else { - fprintf(STDERR, - "The volume %s %u already exists in the VLDB\n", - volname, entry.volumeId[voltype]); - fprintf(STDERR, - "Do you want to do a full/incremental restore or abort? [fia](a): "); - } - dc = c = getchar(); - while (!(dc == EOF || dc == '\n')) - dc = getchar(); /* goto end of line */ - if ((c == 'f') || (c == 'F')) - aoverwrite = FULL; - else if ((c == 'i') || (c == 'I')) - aoverwrite = INC; - else - aoverwrite = ABORT; - } - - if (aoverwrite == ABORT) { - fprintf(STDERR, "Volume exists; Aborting restore command\n"); - exit(1); - } else if (aoverwrite == FULL) { - restoreflags = RV_FULLRST; - fprintf(STDERR, - "Volume exists; Will delete and perform full restore\n"); - } else if (aoverwrite == INC) { - restoreflags = 0; - if (vol_elsewhere) { - fprintf(STDERR, - "%s volume %lu already exists on a different server/part; not allowed\n", - readonly ? "RO" : "RW", (unsigned long)avolid); - exit(1); - } - } - } - if (offline) - restoreflags |= RV_OFFLINE; - if (readonly) - restoreflags |= RV_RDONLY; - code = - UV_RestoreVolume(aserver, apart, avolid, avolname, restoreflags, - WriteData, afilename); - if (code) { - PrintDiagnostics("restore", code); - exit(1); - } - MapPartIdIntoName(apart, apartName); - - /* - * patch typo here - originally "parms[1]", should be "parms[0]" - */ - - fprintf(STDOUT, "Restored volume %s on %s %s\n", avolname, - as->parms[0].items->data, apartName); - return 0; -} - -static -LockReleaseCmd(as) - register struct cmd_syndesc *as; - -{ - afs_int32 avolid, code, err; - - 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); - exit(1); - } - - code = UV_LockRelease(avolid); - if (code) { - PrintDiagnostics("unlock", code); - exit(1); - } - fprintf(STDOUT, "Released lock on vldb entry for volume %s\n", - as->parms[0].items->data); - return 0; -} - -static -AddSite(as) - register struct cmd_syndesc *as; -{ - afs_int32 avolid, aserver, apart, code, err; - char apartName[10], avolname[VOLSER_MAXVOLNAME + 1]; - - vsu_ExtractName(avolname, as->parms[2].items->data);; - avolid = vsu_GetVolumeID(avolname, cstruct, &err); - if (avolid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume '%s'\n", - as->parms[2].items->data); - exit(1); - } - aserver = GetServer(as->parms[0].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - apart = volutil_GetPartitionID(as->parms[1].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } - if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - exit(1); - } - code = UV_AddSite(aserver, apart, avolid); - if (code) { - PrintDiagnostics("addsite", code); - exit(1); - } - MapPartIdIntoName(apart, apartName); - fprintf(STDOUT, "Added replication site %s %s for volume %s\n", - as->parms[0].items->data, apartName, as->parms[2].items->data); - return 0; -} - -static -RemoveSite(as) - register struct cmd_syndesc *as; -{ - - afs_int32 avolid, aserver, apart, code, err; - char apartName[10], avolname[VOLSER_MAXVOLNAME + 1]; - - vsu_ExtractName(avolname, as->parms[2].items->data); - avolid = vsu_GetVolumeID(avolname, cstruct, &err); - if (avolid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume '%s'\n", - as->parms[2].items->data); - exit(1); - } - aserver = GetServer(as->parms[0].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - apart = volutil_GetPartitionID(as->parms[1].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } -/* - *skip the partition validity check, since it is possible that the partition - *has since been decomissioned. - */ -/* - if (!IsPartValid(apart,aserver,&code)){ - if(code) PrintError("",code); - else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data); - exit(1); - } -*/ - code = UV_RemoveSite(aserver, apart, avolid); - if (code) { - PrintDiagnostics("remsite", code); - exit(1); - } - MapPartIdIntoName(apart, apartName); - fprintf(STDOUT, "Removed replication site %s %s for volume %s\n", - as->parms[0].items->data, apartName, as->parms[2].items->data); - return 0; -} - -static -ChangeLocation(as) - register struct cmd_syndesc *as; -{ - afs_int32 avolid, aserver, apart, code, err; - char apartName[10]; - - avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); - if (avolid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume '%s'\n", - as->parms[2].items->data); - exit(1); - } - aserver = GetServer(as->parms[0].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - apart = volutil_GetPartitionID(as->parms[1].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } - if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - exit(1); - } - code = UV_ChangeLocation(aserver, apart, avolid); - if (code) { - PrintDiagnostics("addsite", code); - exit(1); - } - MapPartIdIntoName(apart, apartName); - fprintf(STDOUT, "Changed location to %s %s for volume %s\n", - as->parms[0].items->data, apartName, as->parms[2].items->data); - return 0; -} - -static -ListPartitions(as) - register struct cmd_syndesc *as; -{ - afs_int32 aserver, code; - struct partList dummyPartList; - int i; - char pname[10]; - int total, cnt; - - aserver = GetServer(as->parms[0].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - - - code = UV_ListPartitions(aserver, &dummyPartList, &cnt); - if (code) { - PrintDiagnostics("listpart", code); - exit(1); - } - total = 0; - fprintf(STDOUT, "The partitions on the server are:\n"); - for (i = 0; i < cnt; i++) { - if (dummyPartList.partFlags[i] & PARTVALID) { - memset(pname, 0, sizeof(pname)); - MapPartIdIntoName(dummyPartList.partId[i], pname); - fprintf(STDOUT, " %10s ", pname); - total++; - if ((i % 5) == 0 && (i != 0)) - fprintf(STDOUT, "\n"); - } - } - fprintf(STDOUT, "\n"); - fprintf(STDOUT, "Total: %d\n", total); - return 0; - -} - -static int -CompareVolName(p1, p2) - char *p1, *p2; -{ - volintInfo *arg1, *arg2; - - arg1 = (volintInfo *) p1; - arg2 = (volintInfo *) p2; - return (strcmp(arg1->name, arg2->name)); - -} - -/*------------------------------------------------------------------------ - * PRIVATE XCompareVolName - * - * Description: - * Comparison routine for volume names coming from an extended - * volume listing. - * - * Arguments: - * a_obj1P : Char ptr to first extended vol info object - * a_obj1P : Char ptr to second extended vol info object - * - * Returns: - * The value of strcmp() on the volume names within the passed - * objects (i,e., -1, 0, or 1). - * - * Environment: - * Passed to qsort() as the designated comparison routine. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -static int -XCompareVolName(a_obj1P, a_obj2P) - char *a_obj1P, *a_obj2P; - -{ /*XCompareVolName */ - - return (strcmp - (((struct volintXInfo *)(a_obj1P))->name, - ((struct volintXInfo *)(a_obj2P))->name)); - -} /*XCompareVolName */ - -static int -CompareVolID(p1, p2) - char *p1, *p2; -{ - volintInfo *arg1, *arg2; - - arg1 = (volintInfo *) p1; - arg2 = (volintInfo *) p2; - if (arg1->volid == arg2->volid) - return 0; - if (arg1->volid > arg2->volid) - return 1; - else - return -1; - -} - -/*------------------------------------------------------------------------ - * PRIVATE XCompareVolID - * - * Description: - * Comparison routine for volume IDs coming from an extended - * volume listing. - * - * Arguments: - * a_obj1P : Char ptr to first extended vol info object - * a_obj1P : Char ptr to second extended vol info object - * - * Returns: - * The value of strcmp() on the volume names within the passed - * objects (i,e., -1, 0, or 1). - * - * Environment: - * Passed to qsort() as the designated comparison routine. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -static int -XCompareVolID(a_obj1P, a_obj2P) - char *a_obj1P, *a_obj2P; - -{ /*XCompareVolID */ - - afs_int32 id1, id2; /*Volume IDs we're comparing */ - - id1 = ((struct volintXInfo *)(a_obj1P))->volid; - id2 = ((struct volintXInfo *)(a_obj2P))->volid; - if (id1 == id2) - return (0); - else if (id1 > id2) - return (1); - else - return (-1); - -} /*XCompareVolID */ - -/*------------------------------------------------------------------------ - * PRIVATE ListVolumes - * - * Description: - * Routine used to list volumes, contacting the Volume Server - * directly, bypassing the VLDB. - * - * Arguments: - * as : Ptr to parsed command line arguments. - * - * Returns: - * 0 Successful operation - * - * Environment: - * Nothing interesting. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -static -ListVolumes(as) - register struct cmd_syndesc *as; -{ - afs_int32 apart, int32list, fast; - afs_int32 aserver, code; - volintInfo *pntr, *oldpntr; - afs_int32 count; - int i; - char *base; - volintXInfo *xInfoP, *origxInfoP; /*Ptr to current/orig extended vol info */ - int wantExtendedInfo; /*Do we want extended vol info? */ - - char pname[10]; - struct partList dummyPartList; - int all; - int quiet, cnt; - - apart = -1; - fast = 0; - int32list = 0; - - if (as->parms[3].items) - int32list = 1; - if (as->parms[4].items) - quiet = 1; - else - quiet = 0; - if (as->parms[2].items) - fast = 1; - if (fast) - all = 0; - else - all = 1; - if (as->parms[5].items) { - /* - * We can't coexist with the fast flag. - */ - if (fast) { - fprintf(STDERR, - "vos: Can't use the -fast and -extended flags together\n"); - exit(1); - } - - /* - * We need to turn on ``long'' listings to get the full effect. - */ - wantExtendedInfo = 1; - int32list = 1; - } else - wantExtendedInfo = 0; - if (as->parms[1].items) { - apart = volutil_GetPartitionID(as->parms[1].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } - dummyPartList.partId[0] = apart; - dummyPartList.partFlags[0] = PARTVALID; - cnt = 1; - } - aserver = GetServer(as->parms[0].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - - if (apart != -1) { - if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - exit(1); - } - } else { - code = UV_ListPartitions(aserver, &dummyPartList, &cnt); - if (code) { - PrintDiagnostics("listvol", code); - exit(1); - } - } - for (i = 0; i < cnt; i++) { - if (dummyPartList.partFlags[i] & PARTVALID) { - if (wantExtendedInfo) - code = - UV_XListVolumes(aserver, dummyPartList.partId[i], all, - &xInfoP, &count); - else - code = - UV_ListVolumes(aserver, dummyPartList.partId[i], all, - &pntr, &count); - if (code) { - PrintDiagnostics("listvol", code); - if (pntr) - free(pntr); - exit(1); - } - if (wantExtendedInfo) { - origxInfoP = xInfoP; - base = (char *)xInfoP; - } else { - oldpntr = pntr; - base = (char *)pntr; - } - - if (!fast) { - if (wantExtendedInfo) - qsort(base, count, sizeof(volintXInfo), XCompareVolName); - else - qsort(base, count, sizeof(volintInfo), CompareVolName); - } else { - if (wantExtendedInfo) - qsort(base, count, sizeof(volintXInfo), XCompareVolID); - else - qsort(base, count, sizeof(volintInfo), CompareVolID); - } - MapPartIdIntoName(dummyPartList.partId[i], pname); - if (!quiet) - fprintf(STDOUT, - "Total number of volumes on server %s partition %s: %lu \n", - as->parms[0].items->data, pname, - (unsigned long)count); - if (wantExtendedInfo) { - XDisplayVolumes(aserver, dummyPartList.partId[i], origxInfoP, - count, int32list, fast, quiet); - if (xInfoP) - free(xInfoP); - xInfoP = (volintXInfo *) 0; - } else { -#ifdef FULL_LISTVOL_SWITCH - if (as->parms[6].items) - DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr, - count); - else -#endif /* FULL_LISTVOL_SWITCH */ - DisplayVolumes(aserver, dummyPartList.partId[i], oldpntr, - count, int32list, fast, quiet); - if (pntr) - free(pntr); - pntr = (volintInfo *) 0; - } - } - } - return 0; -} - -static -SyncVldb(as) - register struct cmd_syndesc *as; -{ - afs_int32 pnum, code; /* part name */ - char part[10]; - int flags = 0; - char *volname = 0; - - tserver = 0; - if (as->parms[0].items) { - tserver = GetServer(as->parms[0].items->data); - if (!tserver) { - fprintf(STDERR, "vos: host '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - } - - if (as->parms[1].items) { - pnum = volutil_GetPartitionID(as->parms[1].items->data); - if (pnum < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } - if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos: partition %s does not exist on the server\n", - as->parms[1].items->data); - exit(1); - } - flags = 1; - - if (!tserver) { - fprintf(STDERR, - "The -partition option requires a -server option\n"); - exit(1); - } - } - - if (as->parms[2].items) { - /* Synchronize an individual volume */ - volname = as->parms[2].items->data; - code = UV_SyncVolume(tserver, pnum, volname, flags); - } else { - if (!tserver) { - fprintf(STDERR, - "Without a -volume option, the -server option is required\n"); - exit(1); - } - code = UV_SyncVldb(tserver, pnum, flags, 0 /*unused */ ); - } - - if (code) { - PrintDiagnostics("syncvldb", code); - exit(1); - } - - /* Print a summary of what we did */ - if (volname) - fprintf(STDOUT, "VLDB volume %s synchronized", volname); - else - fprintf(STDOUT, "VLDB synchronized"); - if (tserver) { - fprintf(STDOUT, " with state of server %s", as->parms[0].items->data); - } - if (flags) { - MapPartIdIntoName(pnum, part); - fprintf(STDOUT, " partition %s\n", part); - } - fprintf(STDOUT, "\n"); - - return 0; -} - -static -SyncServer(as) - register struct cmd_syndesc *as; - -{ - afs_int32 pnum, code; /* part name */ - char part[10]; - - int flags = 0; - - tserver = GetServer(as->parms[0].items->data); - if (!tserver) { - fprintf(STDERR, "vos: host '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - if (as->parms[1].items) { - pnum = volutil_GetPartitionID(as->parms[1].items->data); - if (pnum < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } - if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - exit(1); - } - flags = 1; - } else { - pnum = -1; - } - - code = UV_SyncServer(tserver, pnum, flags, 0 /*unused */ ); - if (code) { - PrintDiagnostics("syncserv", code); - exit(1); - } - if (flags) { - MapPartIdIntoName(pnum, part); - fprintf(STDOUT, "Server %s partition %s synchronized with VLDB\n", - as->parms[0].items->data, part); - } else - fprintf(STDOUT, "Server %s synchronized with VLDB\n", - as->parms[0].items->data); - return 0; - -} - -static -VolumeInfoCmd(name) - char *name; -{ - struct nvldbentry entry; - afs_int32 vcode; - - /* The vlserver will handle names with the .readonly - * and .backup extension as well as volume ids. - */ - vcode = VLDB_GetEntryByName(name, &entry); - if (vcode) { - PrintError("", vcode); - exit(1); - } - MapHostToNetwork(&entry); - EnumerateEntry(&entry); - - /* Defect #3027: grubby check to handle locked volume. - * If VLOP_ALLOPERS is set, the entry is locked. - * Leave this routine as is, but put in correct check. - */ - if (entry.flags & VLOP_ALLOPERS) - fprintf(STDOUT, " Volume is currently LOCKED \n"); - - return 0; -} - -static -VolumeZap(as) - register struct cmd_syndesc *as; - -{ - struct nvldbentry entry; - afs_int32 volid, code, server, part, zapbackupid = 0, backupid = 0, err; - - if (as->parms[3].items) { - /* force flag is on, use the other version */ - return NukeVolume(as); - } - - if (as->parms[4].items) { - zapbackupid = 1; - } - - volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); - if (volid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume '%s'\n", - as->parms[2].items->data); - exit(1); - } - part = volutil_GetPartitionID(as->parms[1].items->data); - if (part < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } - server = GetServer(as->parms[0].items->data); - if (!server) { - fprintf(STDERR, "vos: host '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - exit(1); - } - code = VLDB_GetEntryByID(volid, -1, &entry); - if (!code) { - if (volid == entry.volumeId[RWVOL]) - backupid = entry.volumeId[BACKVOL]; - fprintf(STDERR, - "Warning: Entry for volume number %lu exists in VLDB (but we're zapping it anyway!)\n", - (unsigned long)volid); - } - if (zapbackupid) { - volintInfo *pntr = (volintInfo *) 0; - - if (!backupid) { - code = UV_ListOneVolume(server, part, volid, &pntr); - if (!code) { - if (volid == pntr->parentID) - backupid = pntr->backupID; - if (pntr) - free(pntr); - } - } - if (backupid) { - code = UV_VolumeZap(server, part, backupid); - if (code) { - PrintDiagnostics("zap", code); - exit(1); - } - fprintf(STDOUT, "Backup Volume %lu deleted\n", - (unsigned long)backupid); - } - } - code = UV_VolumeZap(server, part, volid); - if (code) { - PrintDiagnostics("zap", code); - exit(1); - } - fprintf(STDOUT, "Volume %lu deleted\n", (unsigned long)volid); - - return 0; -} - -static -VolserStatus(as) - register struct cmd_syndesc *as; - -{ - afs_int32 server, code; - transDebugInfo *pntr, *oldpntr; - afs_int32 count; - int i; - char pname[10]; - - server = GetServer(as->parms[0].items->data); - if (!server) { - fprintf(STDERR, "vos: host '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - code = UV_VolserStatus(server, &pntr, &count); - if (code) { - PrintDiagnostics("status", code); - exit(1); - } - oldpntr = pntr; - if (count == 0) - fprintf(STDOUT, "No active transactions on %s\n", - as->parms[0].items->data); - else { - fprintf(STDOUT, "Total transactions: %d\n", count); - } - for (i = 0; i < count; i++) { - /*print out the relevant info */ - fprintf(STDOUT, "--------------------------------------\n"); - fprintf(STDOUT, "transaction: %lu created: %s", - (unsigned long)pntr->tid, ctime((time_t *) & pntr->time)); - if (pntr->returnCode) { - fprintf(STDOUT, "returnCode: %lu\n", - (unsigned long)pntr->returnCode); - } - if (pntr->iflags) { - fprintf(STDOUT, "attachFlags: "); - switch (pntr->iflags) { - case ITOffline: - fprintf(STDOUT, "offline "); - break; - case ITBusy: - fprintf(STDOUT, "busy "); - break; - case ITReadOnly: - fprintf(STDOUT, "readonly "); - break; - case ITCreate: - fprintf(STDOUT, "create "); - break; - case ITCreateVolID: - fprintf(STDOUT, "create volid "); - break; - } - fprintf(STDOUT, "\n"); - } - if (pntr->vflags) { - fprintf(STDOUT, "volumeStatus: "); - switch (pntr->vflags) { - case VTDeleteOnSalvage: - fprintf(STDOUT, "deleteOnSalvage "); - case VTOutOfService: - fprintf(STDOUT, "outOfService "); - case VTDeleted: - fprintf(STDOUT, "deleted "); - } - fprintf(STDOUT, "\n"); - } - if (pntr->tflags) { - fprintf(STDOUT, "transactionFlags: "); - fprintf(STDOUT, "delete\n"); - } - MapPartIdIntoName(pntr->partition, pname); - fprintf(STDOUT, "volume: %lu partition: %s procedure: %s\n", - (unsigned long)pntr->volid, pname, pntr->lastProcName); - if (pntr->callValid) { - fprintf(STDOUT, - "packetRead: %lu lastReceiveTime: %d packetSend: %lu lastSendTime: %d\n", - (unsigned long)pntr->readNext, pntr->lastReceiveTime, - (unsigned long)pntr->transmitNext, pntr->lastSendTime); - } - pntr++; - fprintf(STDOUT, "--------------------------------------\n"); - fprintf(STDOUT, "\n"); - } - if (oldpntr) - free(oldpntr); - return 0; -} - -static -RenameVolume(as) - register struct cmd_syndesc *as; -{ - afs_int32 code1, code2, code; - struct nvldbentry entry; - - code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry); - if (code1) { - fprintf(STDERR, "vos: Could not find entry for volume %s\n", - as->parms[0].items->data); - exit(1); - } - code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry); - if ((!code1) && (!code2)) { /*the newname already exists */ - fprintf(STDERR, "vos: volume %s already exists\n", - as->parms[1].items->data); - exit(1); - } - - if (code1 && code2) { - fprintf(STDERR, "vos: Could not find entry for volume %s or %s\n", - as->parms[0].items->data, as->parms[1].items->data); - exit(1); - } - if (!VolNameOK(as->parms[0].items->data)) { - fprintf(STDERR, - "Illegal volume name %s, should not end in .readonly or .backup\n", - as->parms[0].items->data); - exit(1); - } - if (!ISNAMEVALID(as->parms[1].items->data)) { - fprintf(STDERR, - "vos: the new volume name %s exceeds the size limit of %d\n", - as->parms[1].items->data, VOLSER_OLDMAXVOLNAME - 10); - exit(1); - } - if (!VolNameOK(as->parms[1].items->data)) { - fprintf(STDERR, - "Illegal volume name %s, should not end in .readonly or .backup\n", - as->parms[1].items->data); - exit(1); - } - if (IsNumeric(as->parms[1].items->data)) { - fprintf(STDERR, "Illegal volume name %s, should not be a number\n", - as->parms[1].items->data); - exit(1); - } - MapHostToNetwork(&entry); - code = - UV_RenameVolume(&entry, as->parms[0].items->data, - as->parms[1].items->data); - if (code) { - PrintDiagnostics("rename", code); - exit(1); - } - fprintf(STDOUT, "Renamed volume %s to %s\n", as->parms[0].items->data, - as->parms[1].items->data); - return 0; -} - -GetVolumeInfo(volid, server, part, voltype, rentry) - afs_int32 *server, volid, *part, *voltype; - register struct nvldbentry *rentry; -{ - afs_int32 vcode; - int i, index = -1; - - vcode = VLDB_GetEntryByID(volid, -1, rentry); - if (vcode) { - fprintf(STDERR, - "Could not fetch the entry for volume %lu from VLDB \n", - (unsigned long)volid); - PrintError("", vcode); - return (vcode); - } - MapHostToNetwork(rentry); - if (volid == rentry->volumeId[ROVOL]) { - *voltype = ROVOL; - for (i = 0; i < rentry->nServers; i++) { - if ((index == -1) && (rentry->serverFlags[i] & ITSROVOL) - && !(rentry->serverFlags[i] & RO_DONTUSE)) - index = i; - } - if (index == -1) { - fprintf(STDERR, - "RO volume is not found in VLDB entry for volume %lu\n", - (unsigned long)volid); - return -1; - } - - *server = rentry->serverNumber[index]; - *part = rentry->serverPartition[index]; - return 0; - } - - index = Lp_GetRwIndex(rentry); - if (index == -1) { - fprintf(STDERR, - "RW Volume is not found in VLDB entry for volume %lu\n", - (unsigned long)volid); - return -1; - } - if (volid == rentry->volumeId[RWVOL]) { - *voltype = RWVOL; - *server = rentry->serverNumber[index]; - *part = rentry->serverPartition[index]; - return 0; - } - if (volid == rentry->volumeId[BACKVOL]) { - *voltype = BACKVOL; - *server = rentry->serverNumber[index]; - *part = rentry->serverPartition[index]; - return 0; - } - fprintf(STDERR, - "unexpected volume type for volume %lu\n", - (unsigned long)volid); - return -1; -} - -static -DeleteEntry(as) - register struct cmd_syndesc *as; - -{ - afs_int32 apart; - afs_int32 avolid; - afs_int32 vcode; - struct VldbListByAttributes attributes; - nbulkentries arrayEntries; - register struct nvldbentry *vllist; - struct cmd_item *itp; - afs_int32 nentries; - int j; - char prefix[VOLSER_MAXVOLNAME + 1]; - int seenprefix = 0; - afs_int32 totalBack = 0, totalFail = 0, err; - - if (as->parms[0].items) { /* -id */ - if (as->parms[1].items || as->parms[2].items || as->parms[3].items) { - fprintf(STDERR, - "You cannot use -server, -partition, or -prefix with the -id argument\n"); - exit(-2); - } - for (itp = as->parms[0].items; itp; itp = itp->next) { - avolid = vsu_GetVolumeID(itp->data, cstruct, &err); - if (avolid == 0) { - if (err) - PrintError("", err); - else - fprintf(STDERR, "vos: can't find volume '%s'\n", - itp->data); - continue; - } - if (as->parms[4].items) { /* -noexecute */ - fprintf(STDOUT, "Would have deleted VLDB entry for %s \n", - itp->data); - fflush(STDOUT); - continue; - } - vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL); - if (vcode) { - fprintf(STDERR, "Could not delete entry for volume %s\n", - itp->data); - fprintf(STDERR, - "You must specify a RW volume name or ID " - "(the entire VLDB entry will be deleted)\n"); - PrintError("", vcode); - totalFail++; - continue; - } - totalBack++; - } - fprintf(STDOUT, "Deleted %d VLDB entries\n", totalBack); - return (totalFail); - } - - if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) { - fprintf(STDERR, "You must specify an option\n"); - exit(-2); - } - - /* Zero out search attributes */ - memset(&attributes, 0, sizeof(struct VldbListByAttributes)); - - if (as->parms[1].items) { /* -prefix */ - strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME); - seenprefix = 1; - if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */ - fprintf(STDERR, - "You must provide -server with the -prefix argument\n"); - exit(-2); - } - } - - if (as->parms[2].items) { /* -server */ - afs_int32 aserver; - aserver = GetServer(as->parms[2].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[2].items->data); - exit(-1); - } - attributes.server = ntohl(aserver); - attributes.Mask |= VLLIST_SERVER; - } - - if (as->parms[3].items) { /* -partition */ - if (!as->parms[2].items) { - fprintf(STDERR, - "You must provide -server with the -partition argument\n"); - exit(-2); - } - apart = volutil_GetPartitionID(as->parms[3].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[3].items->data); - exit(-1); - } - attributes.partition = apart; - attributes.Mask |= VLLIST_PARTITION; - } - - /* Print status line of what we are doing */ - fprintf(STDOUT, "Deleting VLDB entries for "); - if (as->parms[2].items) { - fprintf(STDOUT, "server %s ", as->parms[2].items->data); - } - if (as->parms[3].items) { - char pname[10]; - MapPartIdIntoName(apart, pname); - fprintf(STDOUT, "partition %s ", pname); - } - if (seenprefix) { - fprintf(STDOUT, "which are prefixed with %s ", prefix); - } - fprintf(STDOUT, "\n"); - fflush(STDOUT); - - /* Get all the VLDB entries on a server and/or partition */ - memset(&arrayEntries, 0, sizeof(arrayEntries)); - vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries); - if (vcode) { - fprintf(STDERR, "Could not access the VLDB for attributes\n"); - PrintError("", vcode); - exit(-1); - } - - /* Process each entry */ - for (j = 0; j < nentries; j++) { - vllist = &arrayEntries.nbulkentries_val[j]; - if (seenprefix) { - /* It only deletes the RW volumes */ - if (strncmp(vllist->name, prefix, strlen(prefix))) { - if (verbose) { - fprintf(STDOUT, - "Omitting to delete %s due to prefix %s mismatch\n", - vllist->name, prefix); - } - fflush(STDOUT); - continue; - } - } - - if (as->parms[4].items) { /* -noexecute */ - fprintf(STDOUT, "Would have deleted VLDB entry for %s \n", - vllist->name); - fflush(STDOUT); - continue; - } - - /* Only matches the RW volume name */ - avolid = vllist->volumeId[RWVOL]; - vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL); - if (vcode) { - fprintf(STDOUT, "Could not delete VDLB entry for %s\n", - vllist->name); - totalFail++; - PrintError("", vcode); - continue; - } else { - totalBack++; - if (verbose) - fprintf(STDOUT, "Deleted VLDB entry for %s \n", vllist->name); - } - fflush(STDOUT); - } /*for */ - - fprintf(STDOUT, "----------------------\n"); - fprintf(STDOUT, - "Total VLDB entries deleted: %lu; failed to delete: %lu\n", - (unsigned long)totalBack, (unsigned long)totalFail); - if (arrayEntries.nbulkentries_val) - free(arrayEntries.nbulkentries_val); - return 0; -} - - -static int -CompareVldbEntryByName(p1, p2) - char *p1, *p2; -{ - struct nvldbentry *arg1, *arg2; - - arg1 = (struct nvldbentry *)p1; - arg2 = (struct nvldbentry *)p2; - return (strcmp(arg1->name, arg2->name)); -} - -/* -static int CompareVldbEntry(p1,p2) -char *p1,*p2; -{ - struct nvldbentry *arg1,*arg2; - int i; - int pos1, pos2; - char comp1[100],comp2[100]; - char temp1[20],temp2[20]; - - arg1 = (struct nvldbentry *)p1; - arg2 = (struct nvldbentry *)p2; - pos1 = -1; - pos2 = -1; - - for(i = 0; i < arg1->nServers; i++) - if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i; - for(i = 0; i < arg2->nServers; i++) - if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i; - if(pos1 == -1 || pos2 == -1){ - pos1 = 0; - pos2 = 0; - } - sprintf(comp1,"%10u",arg1->serverNumber[pos1]); - sprintf(comp2,"%10u",arg2->serverNumber[pos2]); - sprintf(temp1,"%10u",arg1->serverPartition[pos1]); - sprintf(temp2,"%10u",arg2->serverPartition[pos2]); - strcat(comp1,temp1); - strcat(comp2,temp2); - strcat(comp1,arg1->name); - strcat(comp1,arg2->name); - return(strcmp(comp1,comp2)); - -} - -*/ -static -ListVLDB(as) - struct cmd_syndesc *as; -{ - afs_int32 apart; - afs_int32 aserver, code; - afs_int32 vcode; - struct VldbListByAttributes attributes; - nbulkentries arrayEntries; - struct nvldbentry *vllist, *tarray = 0, *ttarray; - afs_int32 centries, nentries = 0, tarraysize, parraysize; - int j; - char pname[10]; - int quiet, sort, lock; - afs_int32 thisindex, nextindex; - - aserver = 0; - apart = 0; - - attributes.Mask = 0; - lock = (as->parms[3].items ? 1 : 0); /* -lock flag */ - quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */ - sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */ - - /* If the volume name is given, Use VolumeInfoCmd to look it up - * and not ListAttributes. - */ - if (as->parms[0].items) { - if (lock) { - fprintf(STDERR, - "vos: illegal use of '-locked' switch, need to specify server and/or partition\n"); - exit(1); - } - code = VolumeInfoCmd(as->parms[0].items->data); - if (code) { - PrintError("", code); - exit(1); - } - return 0; - } - - /* Server specified */ - if (as->parms[1].items) { - aserver = GetServer(as->parms[1].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[1].items->data); - exit(1); - } - attributes.server = ntohl(aserver); - attributes.Mask |= VLLIST_SERVER; - } - - /* Partition specified */ - if (as->parms[2].items) { - apart = volutil_GetPartitionID(as->parms[2].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[2].items->data); - exit(1); - } - attributes.partition = apart; - attributes.Mask |= VLLIST_PARTITION; - } - - if (lock) { - attributes.Mask |= VLLIST_FLAG; - attributes.flag = VLOP_ALLOPERS; - } - - /* Print header information */ - if (!quiet) { - MapPartIdIntoName(apart, pname); - fprintf(STDOUT, "VLDB entries for %s %s%s%s %s\n", - (as->parms[1].items ? "server" : "all"), - (as->parms[1].items ? as->parms[1].items->data : "servers"), - (as->parms[2].items ? " partition " : ""), - (as->parms[2].items ? pname : ""), - (lock ? "which are locked:" : "")); - } - - for (thisindex = 0; (thisindex != -1); thisindex = nextindex) { - memset(&arrayEntries, 0, sizeof(arrayEntries)); - centries = 0; - nextindex = -1; - - vcode = - VLDB_ListAttributesN2(&attributes, 0, thisindex, ¢ries, - &arrayEntries, &nextindex); - if (vcode == RXGEN_OPCODE) { - /* Vlserver not running with ListAttributesN2. Fall back */ - vcode = - VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries); - nextindex = -1; - } - if (vcode) { - fprintf(STDERR, "Could not access the VLDB for attributes\n"); - PrintError("", vcode); - exit(1); - } - nentries += centries; - - /* We don't sort, so just print the entries now */ - if (!sort) { - for (j = 0; j < centries; j++) { /* process each entry */ - vllist = &arrayEntries.nbulkentries_val[j]; - MapHostToNetwork(vllist); - EnumerateEntry(vllist); - - if (vllist->flags & VLOP_ALLOPERS) - fprintf(STDOUT, " Volume is currently LOCKED \n"); - } - } - - /* So we sort. First we must collect all the entries and keep - * them in memory. - */ - else if (centries > 0) { - if (!tarray) { - /* steal away the first bulk entries array */ - tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val; - tarraysize = centries * sizeof(struct nvldbentry); - arrayEntries.nbulkentries_val = 0; - } else { - /* Grow the tarray to keep the extra entries */ - parraysize = (centries * sizeof(struct nvldbentry)); - ttarray = - (struct nvldbentry *)realloc(tarray, - tarraysize + parraysize); - if (!ttarray) { - fprintf(STDERR, - "Could not allocate enough space for the VLDB entries\n"); - goto bypass; - } - tarray = ttarray; - - /* Copy them in */ - memcpy(((char *)tarray) + tarraysize, - (char *)arrayEntries.nbulkentries_val, parraysize); - tarraysize += parraysize; - } - } - - /* Free the bulk array */ - if (arrayEntries.nbulkentries_val) { - free(arrayEntries.nbulkentries_val); - arrayEntries.nbulkentries_val = 0; - } - } - - /* Here is where we now sort all the entries and print them */ - if (sort && (nentries > 0)) { - qsort((char *)tarray, nentries, sizeof(struct nvldbentry), - CompareVldbEntryByName); - for (vllist = tarray, j = 0; j < nentries; j++, vllist++) { - MapHostToNetwork(vllist); - EnumerateEntry(vllist); - - if (vllist->flags & VLOP_ALLOPERS) - fprintf(STDOUT, " Volume is currently LOCKED \n"); - } - } - - bypass: - if (!quiet) - fprintf(STDOUT, "\nTotal entries: %lu\n", (unsigned long)nentries); - if (tarray) - free(tarray); - return 0; -} - -static -BackSys(as) - register struct cmd_syndesc *as; -{ - afs_int32 apart = 0, avolid; - afs_int32 aserver = 0, code, aserver1, apart1; - afs_int32 vcode; - struct VldbListByAttributes attributes; - nbulkentries arrayEntries; - register struct nvldbentry *vllist; - afs_int32 nentries; - int j; - char pname[10]; - int seenprefix, seenxprefix, exclude, ex, exp, noaction; - afs_int32 totalBack = 0; - afs_int32 totalFail = 0; - int previdx = -1, error, same; - int comp = 0; - struct cmd_item *ti; - char *ccode; - int match; - - memset(&attributes, 0, sizeof(struct VldbListByAttributes)); - attributes.Mask = 0; - - seenprefix = (as->parms[0].items ? 1 : 0); - exclude = (as->parms[3].items ? 1 : 0); - seenxprefix = (as->parms[4].items ? 1 : 0); - noaction = (as->parms[5].items ? 1 : 0); - - if (as->parms[1].items) { /* -server */ - aserver = GetServer(as->parms[1].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[1].items->data); - exit(1); - } - attributes.server = ntohl(aserver); - attributes.Mask |= VLLIST_SERVER; - } - - if (as->parms[2].items) { /* -partition */ - apart = volutil_GetPartitionID(as->parms[2].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[2].items->data); - exit(1); - } - attributes.partition = apart; - attributes.Mask |= VLLIST_PARTITION; - } - - /* Check to make sure the prefix and xprefix expressions compile ok */ - if (seenprefix) { - for (ti = as->parms[0].items; ti; ti = ti->next) { - if (strncmp(ti->data, "^", 1) == 0) { -#ifdef HAVE_POSIX_REGEX - regex_t re; - char errbuf[256]; - - code = regcomp(&re, ti->data, REG_NOSUB); - if (code != 0) { - regerror(code, &re, errbuf, sizeof errbuf); - fprintf(STDERR, - "Unrecognizable -prefix regular expression: '%s': %s\n", - ti->data, errbuf); - exit(1); - } - regfree(&re); -#else - ccode = (char *)re_comp(ti->data); - if (ccode) { - fprintf(STDERR, - "Unrecognizable -prefix regular expression: '%s': %s\n", - ti->data, ccode); - exit(1); - } -#endif - } - } - } - if (seenxprefix) { - for (ti = as->parms[4].items; ti; ti = ti->next) { - if (strncmp(ti->data, "^", 1) == 0) { -#ifdef HAVE_POSIX_REGEX - regex_t re; - char errbuf[256]; - - code = regcomp(&re, ti->data, REG_NOSUB); - if (code != 0) { - regerror(code, &re, errbuf, sizeof errbuf); - fprintf(STDERR, - "Unrecognizable -xprefix regular expression: '%s': %s\n", - ti->data, errbuf); - exit(1); - } - regfree(&re); -#else - ccode = (char *)re_comp(ti->data); - if (ccode) { - fprintf(STDERR, - "Unrecognizable -xprefix regular expression: '%s': %s\n", - ti->data, ccode); - exit(1); - } -#endif - } - } - } - - memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */ - vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries); - if (vcode) { - fprintf(STDERR, "Could not access the VLDB for attributes\n"); - PrintError("", vcode); - exit(1); - } - - if (as->parms[1].items || as->parms[2].items || verbose) { - fprintf(STDOUT, "%s up volumes", - (noaction ? "Would have backed" : "Backing")); - - if (as->parms[1].items) { - fprintf(STDOUT, " on server %s", as->parms[1].items->data); - } else if (as->parms[2].items) { - fprintf(STDOUT, " for all servers"); - } - - if (as->parms[2].items) { - MapPartIdIntoName(apart, pname); - fprintf(STDOUT, " partition %s", pname); - } - - if (seenprefix || (!seenprefix && seenxprefix)) { - ti = (seenprefix ? as->parms[0].items : as->parms[4].items); - ex = (seenprefix ? exclude : !exclude); - exp = (strncmp(ti->data, "^", 1) == 0); - fprintf(STDOUT, " which %smatch %s '%s'", (ex ? "do not " : ""), - (exp ? "expression" : "prefix"), ti->data); - for (ti = ti->next; ti; ti = ti->next) { - exp = (strncmp(ti->data, "^", 1) == 0); - printf(" %sor %s '%s'", (ex ? "n" : ""), - (exp ? "expression" : "prefix"), ti->data); - } - } - - if (seenprefix && seenxprefix) { - ti = as->parms[4].items; - exp = (strncmp(ti->data, "^", 1) == 0); - fprintf(STDOUT, " %swhich match %s '%s'", - (exclude ? "adding those " : "removing those "), - (exp ? "expression" : "prefix"), ti->data); - for (ti = ti->next; ti; ti = ti->next) { - exp = (strncmp(ti->data, "^", 1) == 0); - printf(" or %s '%s'", (exp ? "expression" : "prefix"), - ti->data); - } - } - fprintf(STDOUT, " .. "); - if (verbose) - fprintf(STDOUT, "\n"); - fflush(STDOUT); - } - - for (j = 0; j < nentries; j++) { /* process each vldb entry */ - vllist = &arrayEntries.nbulkentries_val[j]; - - if (seenprefix) { - for (ti = as->parms[0].items; ti; ti = ti->next) { - if (strncmp(ti->data, "^", 1) == 0) { -#ifdef HAVE_POSIX_REGEX - regex_t re; - char errbuf[256]; - - /* XXX -- should just do the compile once! */ - code = regcomp(&re, ti->data, REG_NOSUB); - if (code != 0) { - regerror(code, &re, errbuf, sizeof errbuf); - fprintf(STDERR, - "Error in -prefix regular expression: '%s': %s\n", - ti->data, errbuf); - exit(1); - } - match = (regexec(&re, vllist->name, 0, NULL, 0) == 0); - regfree(&re); -#else - ccode = (char *)re_comp(ti->data); - if (ccode) { - fprintf(STDERR, - "Error in -prefix regular expression: '%s': %s\n", - ti->data, ccode); - exit(1); - } - match = (re_exec(vllist->name) == 1); -#endif - } else { - match = - (strncmp(vllist->name, ti->data, strlen(ti->data)) == - 0); - } - if (match) - break; - } - } else { - match = 1; - } - - /* Without the -exclude flag: If it matches the prefix, then - * check if we want to exclude any from xprefix. - * With the -exclude flag: If it matches the prefix, then - * check if we want to add any from xprefix. - */ - if (match && seenxprefix) { - for (ti = as->parms[4].items; ti; ti = ti->next) { - if (strncmp(ti->data, "^", 1) == 0) { -#ifdef HAVE_POSIX_REGEX - regex_t re; - char errbuf[256]; - - /* XXX -- should just do the compile once! */ - code = regcomp(&re, ti->data, REG_NOSUB); - if (code != 0) { - regerror(code, &re, errbuf, sizeof errbuf); - fprintf(STDERR, - "Error in -xprefix regular expression: '%s': %s\n", - ti->data, errbuf); - exit(1); - } - if (regexec(&re, vllist->name, 0, NULL, 0) == 0) - match = 0; - regfree(&re); -#else - ccode = (char *)re_comp(ti->data); - if (ccode) { - fprintf(STDERR, - "Error in -xprefix regular expression: '%s': %s\n", - ti->data, ccode); - exit(1); - } - if (re_exec(vllist->name) == 1) { - match = 0; - break; - } -#endif - } else { - if (strncmp(vllist->name, ti->data, strlen(ti->data)) == - 0) { - match = 0; - break; - } - } - } - } - - if (exclude) - match = !match; /* -exclude will reverse the match */ - if (!match) - continue; /* Skip if no match */ - - /* Print list of volumes to backup */ - if (noaction) { - fprintf(STDOUT, " %s\n", vllist->name); - continue; - } - - if (!(vllist->flags & RW_EXISTS)) { - if (verbose) { - fprintf(STDOUT, - "Omitting to backup %s since RW volume does not exist \n", - vllist->name); - fprintf(STDOUT, "\n"); - } - fflush(STDOUT); - continue; - } - - avolid = vllist->volumeId[RWVOL]; - MapHostToNetwork(vllist); - GetServerAndPart(vllist, RWVOL, &aserver1, &apart1, &previdx); - if (aserver1 == -1 || apart1 == -1) { - fprintf(STDOUT, "could not backup %s, invalid VLDB entry\n", - vllist->name); - totalFail++; - continue; - } - if (aserver) { - same = VLDB_IsSameAddrs(aserver, aserver1, &error); - if (error) { - fprintf(STDERR, - "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n", - aserver, error); - totalFail++; - continue; - } - } - if ((aserver && !same) || (apart && (apart != apart1))) { - if (verbose) { - fprintf(STDOUT, - "Omitting to backup %s since the RW is in a different location\n", - vllist->name); - } - continue; - } - if (verbose) { - time_t now = time(0); - fprintf(STDOUT, "Creating backup volume for %s on %s", - vllist->name, ctime(&now)); - fflush(STDOUT); - } - - code = UV_BackupVolume(aserver1, apart1, avolid); - if (code) { - fprintf(STDOUT, "Could not backup %s\n", vllist->name); - totalFail++; - } else { - totalBack++; - } - if (verbose) - fprintf(STDOUT, "\n"); - fflush(STDOUT); - } /* process each vldb entry */ - fprintf(STDOUT, "done\n"); - fprintf(STDOUT, "Total volumes backed up: %lu; failed to backup: %lu\n", - (unsigned long)totalBack, (unsigned long)totalFail); - fflush(STDOUT); - if (arrayEntries.nbulkentries_val) - free(arrayEntries.nbulkentries_val); - return 0; -} - -static -UnlockVLDB(as) - register struct cmd_syndesc *as; -{ - afs_int32 apart; - afs_int32 aserver, code; - afs_int32 vcode; - struct VldbListByAttributes attributes; - nbulkentries arrayEntries; - register struct nvldbentry *vllist; - afs_int32 nentries; - int j; - afs_int32 volid; - afs_int32 totalE; - char pname[10]; - - apart = -1; - totalE = 0; - attributes.Mask = 0; - - if (as->parms[0].items) { /* server specified */ - aserver = GetServer(as->parms[0].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - attributes.server = ntohl(aserver); - attributes.Mask |= VLLIST_SERVER; - } - if (as->parms[1].items) { /* partition specified */ - apart = volutil_GetPartitionID(as->parms[1].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } - if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - exit(1); - } - attributes.partition = apart; - attributes.Mask |= VLLIST_PARTITION; - } - attributes.flag = VLOP_ALLOPERS; - attributes.Mask |= VLLIST_FLAG; - memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */ - vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries); - if (vcode) { - fprintf(STDERR, "Could not access the VLDB for attributes\n"); - PrintError("", vcode); - exit(1); - } - for (j = 0; j < nentries; j++) { /* process each entry */ - vllist = &arrayEntries.nbulkentries_val[j]; - volid = vllist->volumeId[RWVOL]; - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, volid, -1, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, "Could not unlock entry for volume %s\n", - vllist->name); - PrintError("", vcode); - totalE++; - } - - } - MapPartIdIntoName(apart, pname); - if (totalE) - fprintf(STDOUT, - "Could not lock %lu VLDB entries of %lu locked entries\n", - (unsigned long)totalE, (unsigned long)nentries); - else { - if (as->parms[0].items) { - fprintf(STDOUT, - "Unlocked all the VLDB entries for volumes on server %s ", - as->parms[0].items->data); - if (as->parms[1].items) { - MapPartIdIntoName(apart, pname); - fprintf(STDOUT, "partition %s\n", pname); - } else - fprintf(STDOUT, "\n"); - - } else if (as->parms[1].items) { - MapPartIdIntoName(apart, pname); - fprintf(STDOUT, - "Unlocked all the VLDB entries for volumes on partition %s on all servers\n", - pname); - } - } - - if (arrayEntries.nbulkentries_val) - free(arrayEntries.nbulkentries_val); - return 0; -} - -static -PartitionInfo(as) - register struct cmd_syndesc *as; -{ - afs_int32 apart; - afs_int32 aserver, code; - char pname[10]; - struct diskPartition partition; - struct partList dummyPartList; - int i, cnt; - - apart = -1; - aserver = GetServer(as->parms[0].items->data); - if (aserver == 0) { - fprintf(STDERR, "vos: server '%s' not found in host table\n", - as->parms[0].items->data); - exit(1); - } - if (as->parms[1].items) { - apart = volutil_GetPartitionID(as->parms[1].items->data); - if (apart < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - exit(1); - } - dummyPartList.partId[0] = apart; - dummyPartList.partFlags[0] = PARTVALID; - cnt = 1; - } - if (apart != -1) { - if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */ - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - exit(1); - } - } else { - code = UV_ListPartitions(aserver, &dummyPartList, &cnt); - if (code) { - PrintDiagnostics("listpart", code); - exit(1); - } - } - for (i = 0; i < cnt; i++) { - if (dummyPartList.partFlags[i] & PARTVALID) { - MapPartIdIntoName(dummyPartList.partId[i], pname); - code = UV_PartitionInfo(aserver, pname, &partition); - if (code) { - fprintf(STDERR, "Could not get information on partition %s\n", - pname); - PrintError("", code); - exit(1); - } - fprintf(STDOUT, - "Free space on partition %s: %d K blocks out of total %d\n", - pname, partition.free, partition.minFree); - } - } - return 0; -} - -static -ChangeAddr(as) - register struct cmd_syndesc *as; - -{ - afs_int32 ip1, ip2, vcode; - int remove = 0; - - ip1 = GetServer(as->parms[0].items->data); - if (!ip1) { - fprintf(STDERR, "vos: invalid host address\n"); - return (EINVAL); - } - - if ((as->parms[1].items && as->parms[2].items) - || (!as->parms[1].items && !as->parms[2].items)) { - fprintf(STDERR, - "vos: Must specify either '-newaddr ' or '-remove' flag\n"); - return (EINVAL); - } - - if (as->parms[1].items) { - ip2 = GetServer(as->parms[1].items->data); - if (!ip2) { - fprintf(STDERR, "vos: invalid host address\n"); - return (EINVAL); - } - } else { - /* Play a trick here. If we are removing an address, ip1 will be -1 - * and ip2 will be the original address. This switch prevents an - * older revision vlserver from removing the IP address. - */ - remove = 1; - ip2 = ip1; - ip1 = 0xffffffff; - } - - vcode = ubik_Call_New(VL_ChangeAddr, cstruct, 0, ntohl(ip1), ntohl(ip2)); - if (vcode) { - if (remove) { - fprintf(STDERR, "Could not remove server %s from the VLDB\n", - as->parms[0].items->data); - if (vcode == VL_NOENT) { - fprintf(STDERR, - "vlserver does not support the remove flag or "); - } - } else { - fprintf(STDERR, "Could not change server %s to server %s\n", - as->parms[0].items->data, as->parms[1].items->data); - } - PrintError("", vcode); - return (vcode); - } - - if (remove) { - fprintf(STDOUT, "Removed server %s from the VLDB\n", - as->parms[0].items->data); - } else { - fprintf(STDOUT, "Changed server %s to server %s\n", - as->parms[0].items->data, as->parms[1].items->data); - } - return 0; -} - -static void -print_addrs(const bulkaddrs * addrs, const afsUUID * m_uuid, int nentries, - int print, int noresolve) -{ - afs_int32 vcode; - afs_int32 i, j; - struct VLCallBack vlcb; - afs_int32 *addrp; - bulkaddrs m_addrs; - ListAddrByAttributes m_attrs; - afs_int32 m_nentries, *m_addrp; - afs_int32 base, index; - char buf[1024]; - - if (print) { - afsUUID_to_string(m_uuid, buf, sizeof(buf)); - printf("UUID: %s\n", buf); - } - - /* print out the list of all the server */ - addrp = (afs_int32 *) addrs->bulkaddrs_val; - for (i = 0; i < nentries; i++, addrp++) { - /* If it is a multihomed address, then we will need to - * get the addresses for this multihomed server from - * the vlserver and print them. - */ - if (((*addrp & 0xff000000) == 0xff000000) && ((*addrp) & 0xffff)) { - /* Get the list of multihomed fileservers */ - base = (*addrp >> 16) & 0xff; - index = (*addrp) & 0xffff; - - if ((base >= 0) && (base <= VL_MAX_ADDREXTBLKS) && (index >= 1) - && (index <= VL_MHSRV_PERBLK)) { - m_attrs.Mask = VLADDR_INDEX; - m_attrs.index = (base * VL_MHSRV_PERBLK) + index; - m_nentries = 0; - m_addrs.bulkaddrs_val = 0; - m_addrs.bulkaddrs_len = 0; - vcode = - ubik_Call(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid, - &vlcb, &m_nentries, &m_addrs); - if (vcode) { - fprintf(STDERR, - "vos: could not list the multi-homed server addresses\n"); - PrintError("", vcode); - } - - /* Print the list */ - m_addrp = (afs_int32 *) m_addrs.bulkaddrs_val; - for (j = 0; j < m_nentries; j++, m_addrp++) { - *m_addrp = htonl(*m_addrp); - if (noresolve) { - char hoststr[16]; - printf("%s ", afs_inet_ntoa_r(*m_addrp, hoststr)); - } else { - printf("%s ", hostutil_GetNameByINet(*m_addrp)); - } - } - if (j == 0) { - printf("\n"); - } else { - printf("\n"); - } - - continue; - } - } - - /* Otherwise, it is a non-multihomed entry and contains - * the IP address of the server - print it. - */ - *addrp = htonl(*addrp); - if (noresolve) { - char hoststr[16]; - printf("%s\n", afs_inet_ntoa_r(*addrp, hoststr)); - } else { - printf("%s\n", hostutil_GetNameByINet(*addrp)); - } - } - - if (print) { - printf("\n"); - } - return; -} - -static -ListAddrs(as) - register struct cmd_syndesc *as; -{ - afs_int32 vcode; - afs_int32 i, noresolve = 0, printuuid = 0; - struct VLCallBack vlcb; - afs_int32 nentries; - bulkaddrs m_addrs; - ListAddrByAttributes m_attrs; - afsUUID m_uuid, askuuid; - afs_int32 m_nentries; - - memset(&m_attrs, 0, sizeof(struct ListAddrByAttributes)); - m_attrs.Mask = VLADDR_INDEX; - - memset(&m_addrs, 0, sizeof(bulkaddrs)); - memset(&askuuid, 0, sizeof(afsUUID)); - if (as->parms[0].items) { - /* -uuid */ - afsUUID_from_string(as->parms[0].items->data, &askuuid); - m_attrs.Mask = VLADDR_UUID; - m_attrs.uuid = askuuid; - } - if (as->parms[1].items) { - /* -host */ - struct hostent *he; - afs_int32 saddr; - he = hostutil_GetHostByName((char *)as->parms[1].items->data); - if (he == NULL) { - fprintf(stderr, "Can't get host info for '%s'\n", - as->parms[1].items->data); - exit(-1); - } - memcpy(&saddr, he->h_addr, 4); - m_attrs.Mask = VLADDR_IPADDR; - m_attrs.ipaddr = ntohl(saddr); - } - if (as->parms[2].items) { - noresolve = 1; - } - if (as->parms[3].items) { - printuuid = 1; - } - - m_addrs.bulkaddrs_val = 0; - m_addrs.bulkaddrs_len = 0; - - vcode = - ubik_Call_New(VL_GetAddrs, cstruct, 0, 0, 0, &vlcb, &nentries, - &m_addrs); - if (vcode) { - fprintf(STDERR, "vos: could not list the server addresses\n"); - PrintError("", vcode); - return (vcode); - } - - m_nentries = 0; - m_addrs.bulkaddrs_val = 0; - m_addrs.bulkaddrs_len = 0; - i = 1; - while (1) { - m_attrs.index = i; - - vcode = - ubik_Call_New(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid, - &vlcb, &m_nentries, &m_addrs); - if (vcode == VL_NOENT) { - i++; - nentries++; - continue; - } - - if (vcode == VL_INDEXERANGE) { - break; - } - - if (vcode) { - fprintf(STDERR, "vos: could not list the server addresses\n"); - PrintError("", vcode); - return (vcode); - } - - print_addrs(&m_addrs, &m_uuid, m_nentries, printuuid, noresolve); - i++; - - if ((as->parms[1].items) || (as->parms[0].items) || (i > nentries)) - break; - } - - return 0; -} - -static -LockEntry(as) - register struct cmd_syndesc *as; - -{ - afs_int32 avolid, vcode, err; - - 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); - exit(1); - } - vcode = ubik_Call(VL_SetLock, cstruct, 0, avolid, -1, VLOP_DELETE); - if (vcode) { - fprintf(STDERR, "Could not lock VLDB entry for volume %s\n", - as->parms[0].items->data); - PrintError("", vcode); - exit(1); - } - fprintf(STDOUT, "Locked VLDB entry for volume %s\n", - as->parms[0].items->data); - return 0; -} - -static -ConvertRO(as) - register struct cmd_syndesc *as; - -{ - afs_int32 partition = -1; - afs_int32 server, volid, code, i, same; - struct nvldbentry entry, storeEntry; - afs_int32 vcode; - afs_int32 rwindex; - afs_int32 rwserver = 0; - afs_int32 rwpartition; - afs_int32 roindex; - afs_int32 roserver = 0; - afs_int32 ropartition; - int force = 0; - struct rx_connection *aconn; - char c, dc; - - server = GetServer(as->parms[0].items->data); - if (!server) { - fprintf(STDERR, "vos: host '%s' not found in host table\n", - as->parms[0].items->data); - return ENOENT; - } - partition = volutil_GetPartitionID(as->parms[1].items->data); - if (partition < 0) { - fprintf(STDERR, "vos: could not interpret partition name '%s'\n", - as->parms[1].items->data); - return ENOENT; - } - if (!IsPartValid(partition, server, &code)) { - if (code) - PrintError("", code); - else - fprintf(STDERR, - "vos : partition %s does not exist on the server\n", - as->parms[1].items->data); - return ENOENT; - } - volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &code); - if (volid == 0) { - if (code) - PrintError("", code); - else - fprintf(STDERR, "Unknown volume ID or name '%s'\n", - as->parms[0].items->data); - return -1; - } - if (as->parms[3].items) - force = 1; - - vcode = VLDB_GetEntryByID(volid, -1, &entry); - if (vcode) { - fprintf(STDERR, - "Could not fetch the entry for volume %lu from VLDB\n", - (unsigned long)volid); - PrintError("convertROtoRW", code); - return vcode; - } - - /* use RO volid even if user specified RW or BK volid */ - - if (volid != entry.volumeId[ROVOL]) - volid = entry.volumeId[ROVOL]; - - MapHostToNetwork(&entry); - for (i = 0; i < entry.nServers; i++) { - if (entry.serverFlags[i] & ITSRWVOL) { - rwindex = i; - rwserver = entry.serverNumber[i]; - rwpartition = entry.serverPartition[i]; - } - if (entry.serverFlags[i] & ITSROVOL) { - same = VLDB_IsSameAddrs(server, entry.serverNumber[i], &code); - if (code) { - fprintf(STDERR, - "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n", - server, code); - return ENOENT; - } - if (same) { - roindex = i; - roserver = entry.serverNumber[i]; - ropartition = entry.serverPartition[i]; - break; - } - } - } - if (!roserver) { - fprintf(STDERR, "Warning: RO volume didn't exist in vldb!\n"); - } - if (ropartition != partition) { - fprintf(STDERR, - "Warning: RO volume should be in partition %d instead of %d (vldb)\n", - ropartition, partition); - } - - if (rwserver) { - fprintf(STDERR, - "VLDB indicates that a RW volume exists already on %s in partition %s.\n", - hostutil_GetNameByINet(rwserver), - volutil_PartitionName(rwpartition)); - if (!force) { - fprintf(STDERR, "Overwrite this VLDB entry? [y|n] (n)\n"); - dc = c = getchar(); - while (!(dc == EOF || dc == '\n')) - dc = getchar(); /* goto end of line */ - if ((c != 'y') && (c != 'Y')) { - fprintf(STDERR, "aborted.\n"); - return -1; - } - } - } - - vcode = - ubik_Call(VL_SetLock, cstruct, 0, entry.volumeId[RWVOL], RWVOL, - VLOP_MOVE); - aconn = UV_Bind(server, AFSCONF_VOLUMEPORT); - code = AFSVolConvertROtoRWvolume(aconn, partition, volid); - if (code) { - fprintf(STDERR, - "Converting RO volume %lu to RW volume failed with code %d\n", - (unsigned long)volid, code); - PrintError("convertROtoRW ", code); - return -1; - } - entry.serverFlags[roindex] = ITSRWVOL; - entry.flags |= RW_EXISTS; - entry.flags &= ~BACK_EXISTS; - if (rwserver) { - (entry.nServers)--; - if (rwindex != entry.nServers) { - entry.serverNumber[rwindex] = entry.serverNumber[entry.nServers]; - entry.serverPartition[rwindex] = - entry.serverPartition[entry.nServers]; - entry.serverFlags[rwindex] = entry.serverFlags[entry.nServers]; - entry.serverNumber[entry.nServers] = 0; - entry.serverPartition[entry.nServers] = 0; - entry.serverFlags[entry.nServers] = 0; - } - } - entry.flags &= ~RO_EXISTS; - for (i = 0; i < entry.nServers; i++) { - if (entry.serverFlags[i] & ITSROVOL) { - if (!(entry.serverFlags[i] & (RO_DONTUSE | NEW_REPSITE))) - entry.flags |= RO_EXISTS; - } - } - MapNetworkToHost(&entry, &storeEntry); - code = - VLDB_ReplaceEntry(entry.volumeId[RWVOL], RWVOL, &storeEntry, - (LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP)); - if (code) { - fprintf(STDERR, - "Warning: volume converted, but vldb update failed with code %d!\n", - code); - } - vcode = UV_LockRelease(entry.volumeId[RWVOL]); - if (vcode) { - PrintDiagnostics("unlock", vcode); - } - 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 */ -#ifdef AFS_64BIT_ENV - vol_size.dump_size = 0; -#else - FillInt64(vol_size.dump_size,0, 1); -#endif - 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; -{ - if (acode == EACCES) { - fprintf(STDERR, - "You are not authorized to perform the 'vos %s' command (%d)\n", - astring, acode); - } else { - fprintf(STDERR, "Error in vos %s command.\n", astring); - PrintError("", acode); - } - return 0; -} - - -static -MyBeforeProc(as, arock) - struct cmd_syndesc *as; - char *arock; -{ - register char *tcell; - register afs_int32 code; - register afs_int32 sauth; - - /* Initialize the ubik_client connection */ - rx_SetRxDeadTime(90); - cstruct = (struct ubik_client *)0; - - sauth = 0; - tcell = NULL; - if (as->parms[12].items) /* if -cell specified */ - tcell = as->parms[12].items->data; - if (as->parms[14].items) /* -serverauth specified */ - sauth = 1; - if (as->parms[16].items) /* -crypt specified */ - vsu_SetCrypt(1); - if ((code = - vsu_ClientInit((as->parms[13].items != 0), confdir, tcell, sauth, - &cstruct, UV_SetSecurity))) { - fprintf(STDERR, "could not initialize VLDB library (code=%lu) \n", - (unsigned long)code); - exit(1); - } - rxInitDone = 1; - if (as->parms[15].items) /* -verbose flag set */ - verbose = 1; - else - verbose = 0; - return 0; -} - -int -osi_audit() -{ -/* this sucks but it works for now. -*/ - return 0; -} - -#include "AFS_component_version_number.c" - -main(argc, argv) - int argc; - char **argv; -{ - register afs_int32 code; - - register struct cmd_syndesc *ts; - -#ifdef AFS_AIX32_ENV - /* - * The following signal action for AIX is necessary so that in case of a - * crash (i.e. core is generated) we can include the user's data section - * in the core dump. Unfortunately, by default, only a partial core is - * generated which, in many cases, isn't too useful. - */ - struct sigaction nsa; - - sigemptyset(&nsa.sa_mask); - nsa.sa_handler = SIG_DFL; - nsa.sa_flags = SA_FULLDUMP; - sigaction(SIGSEGV, &nsa, NULL); -#endif - - confdir = AFSDIR_CLIENT_ETC_DIRPATH; - - cmd_SetBeforeProc(MyBeforeProc, NULL); - - ts = cmd_CreateSyntax("create", CreateVolume, 0, "create a new volume"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name"); - cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "volume name"); - cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, - "initial quota (KB)"); -#ifdef notdef - cmd_AddParm(ts, "-minquota", CMD_SINGLE, CMD_OPTIONAL, ""); -#endif - COMMONPARMS; - - ts = cmd_CreateSyntax("remove", DeleteVolume, 0, "delete a volume"); - cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - - COMMONPARMS; - - ts = cmd_CreateSyntax("move", MoveVolume, 0, "move a volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source"); - cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0, - "partition name on source"); - cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0, - "machine name on destination"); - cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0, - "partition name on destination"); - cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL, - "copy live volume without cloning"); - COMMONPARMS; - - ts = cmd_CreateSyntax("copy", CopyVolume, 0, "copy a volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source"); - cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source"); - cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0, - "partition name on source"); - cmd_AddParm(ts, "-toname", CMD_SINGLE, 0, "volume name on destination"); - cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0, - "machine name on destination"); - cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0, - "partition name on destination"); - cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL, - "leave new volume offline"); - cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL, - "make new volume read-only"); - cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL, - "copy live volume without cloning"); - COMMONPARMS; - - ts = cmd_CreateSyntax("shadow", ShadowVolume, 0, - "make or update a shadow volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source"); - cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source"); - cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0, - "partition name on source"); - cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0, - "machine name on destination"); - cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0, - "partition name on destination"); - cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL, - "volume name on destination"); - cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL, - "volume ID on destination"); - cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL, - "leave shadow volume offline"); - cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL, - "make shadow volume read-only"); - cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL, - "copy live volume without cloning"); - cmd_AddParm(ts, "-incremental", CMD_FLAG, CMD_OPTIONAL, - "do incremental update if target exists"); - COMMONPARMS; - - ts = cmd_CreateSyntax("backup", BackupVolume, 0, - "make backup of a volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - COMMONPARMS; - - ts = cmd_CreateSyntax("clone", CloneVolume, 0, - "make clone of a volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition"); - cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL, - "volume name on destination"); - cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL, - "volume ID on destination"); - cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL, - "leave clone volume offline"); - cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL, - "make clone volume read-only, not readwrite"); - COMMONPARMS; - - ts = cmd_CreateSyntax("release", ReleaseVolume, 0, "release a volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, - "force a complete release"); - COMMONPARMS; - - ts = cmd_CreateSyntax("dump", DumpVolume, 0, "dump a volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time"); - cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file"); - cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition"); - cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL, - "dump a clone of the volume"); - COMMONPARMS; - - ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name"); - cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "name of volume to be restored"); - cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file"); - cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "volume ID"); - cmd_AddParm(ts, "-overwrite", CMD_SINGLE, CMD_OPTIONAL, - "abort | full | incremental"); - cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL, - "leave restored volume offline"); - cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL, - "make restored volume read-only"); - COMMONPARMS; - - ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0, - "release lock on VLDB entry for a volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - COMMONPARMS; - - ts = cmd_CreateSyntax("changeloc", ChangeLocation, 0, - "change an RW volume's location in the VLDB"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, - "machine name for new location"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, - "partition name for new location"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - COMMONPARMS; - - ts = cmd_CreateSyntax("addsite", AddSite, 0, "add a replication site"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new site"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, - "partition name for new site"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - COMMONPARMS; - - ts = cmd_CreateSyntax("remsite", RemoveSite, 0, - "remove a replication site"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - COMMONPARMS; - - ts = cmd_CreateSyntax("listpart", ListPartitions, 0, "list partitions"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - COMMONPARMS; - - ts = cmd_CreateSyntax("listvol", ListVolumes, 0, - "list volumes on server (bypass VLDB)"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); - cmd_AddParm(ts, "-fast", CMD_FLAG, CMD_OPTIONAL, "minimal listing"); - cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, - "list all normal volume fields"); - cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, - "generate minimal information"); - cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL, - "list extended volume fields"); -#ifdef FULL_LISTVOL_SWITCH - cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL, - "machine readable format"); -#endif /* FULL_LISTVOL_SWITCH */ - COMMONPARMS; - - ts = cmd_CreateSyntax("syncvldb", SyncVldb, 0, - "synchronize VLDB with server"); - cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); - cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID"); - COMMONPARMS; - - ts = cmd_CreateSyntax("syncserv", SyncServer, 0, - "synchronize server with VLDB"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); - COMMONPARMS; - - ts = cmd_CreateSyntax("examine", ExamineVolume, 0, - "everything about the volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL, - "list extended volume fields"); -#ifdef FULL_LISTVOL_SWITCH - cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL, - "machine readable format"); -#endif /* FULL_LISTVOL_SWITCH */ - COMMONPARMS; - cmd_CreateAlias(ts, "volinfo"); - - ts = cmd_CreateSyntax("setfields", SetFields, 0, - "change volume info fields"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)"); - cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse"); - COMMONPARMS; - - ts = cmd_CreateSyntax("offline", volOffline, 0, (char *)CMD_HIDDEN); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - cmd_AddParm(ts, "-sleep", CMD_SINGLE, CMD_OPTIONAL, "seconds to sleep"); - cmd_AddParm(ts, "-busy", CMD_FLAG, CMD_OPTIONAL, "busy volume"); - COMMONPARMS; - - ts = cmd_CreateSyntax("online", volOnline, 0, (char *)CMD_HIDDEN); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - COMMONPARMS; - - ts = cmd_CreateSyntax("zap", VolumeZap, 0, - "delete the volume, don't bother with VLDB"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume ID"); - cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, - "force deletion of bad volumes"); - cmd_AddParm(ts, "-backup", CMD_FLAG, CMD_OPTIONAL, - "also delete backup volume if one is found"); - COMMONPARMS; - - ts = cmd_CreateSyntax("status", VolserStatus, 0, - "report on volser status"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - COMMONPARMS; - - ts = cmd_CreateSyntax("rename", RenameVolume, 0, "rename a volume"); - cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old volume name "); - cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new volume name "); - COMMONPARMS; - - ts = cmd_CreateSyntax("listvldb", ListVLDB, 0, - "list volumes in the VLDB"); - cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID"); - cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); - cmd_AddParm(ts, "-locked", CMD_FLAG, CMD_OPTIONAL, "locked volumes only"); - cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, - "generate minimal information"); - cmd_AddParm(ts, "-nosort", CMD_FLAG, CMD_OPTIONAL, - "do not alphabetically sort the volume names"); - COMMONPARMS; - - ts = cmd_CreateSyntax("backupsys", BackSys, 0, "en masse backups"); - cmd_AddParm(ts, "-prefix", CMD_LIST, CMD_OPTIONAL, - "common prefix on volume(s)"); - cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); - cmd_AddParm(ts, "-exclude", CMD_FLAG, CMD_OPTIONAL, - "exclude common prefix volumes"); - cmd_AddParm(ts, "-xprefix", CMD_LIST, CMD_OPTIONAL, - "negative prefix on volume(s)"); - cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "no action"); - COMMONPARMS; - - ts = cmd_CreateSyntax("delentry", DeleteEntry, 0, - "delete VLDB entry for a volume"); - cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "volume name or ID"); - cmd_AddParm(ts, "-prefix", CMD_SINGLE, CMD_OPTIONAL, - "prefix of the volume whose VLDB entry is to be deleted"); - cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); - cmd_AddParm(ts, "-noexecute", CMD_FLAG, CMD_OPTIONAL | CMD_HIDE, - "no execute"); - COMMONPARMS; - - ts = cmd_CreateSyntax("partinfo", PartitionInfo, 0, - "list partition information"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); - COMMONPARMS; - - ts = cmd_CreateSyntax("unlockvldb", UnlockVLDB, 0, - "unlock all the locked entries in the VLDB"); - cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); - COMMONPARMS; - - ts = cmd_CreateSyntax("lock", LockEntry, 0, - "lock VLDB entry for a volume"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - COMMONPARMS; - - ts = cmd_CreateSyntax("changeaddr", ChangeAddr, 0, - "change the IP address of a file server"); - cmd_AddParm(ts, "-oldaddr", CMD_SINGLE, 0, "original IP address"); - cmd_AddParm(ts, "-newaddr", CMD_SINGLE, CMD_OPTIONAL, "new IP address"); - cmd_AddParm(ts, "-remove", CMD_FLAG, CMD_OPTIONAL, - "remove the IP address from the VLDB"); - COMMONPARMS; - - ts = cmd_CreateSyntax("listaddrs", ListAddrs, 0, - "list the IP address of all file servers registered in the VLDB"); - cmd_AddParm(ts, "-uuid", CMD_SINGLE, CMD_OPTIONAL, "uuid of server"); - cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_OPTIONAL, "address of host"); - cmd_AddParm(ts, "-noresolve", CMD_FLAG, CMD_OPTIONAL, - "don't resolve addresses"); - cmd_AddParm(ts, "-printuuid", CMD_FLAG, CMD_OPTIONAL, - "print uuid of hosts"); - COMMONPARMS; - - ts = cmd_CreateSyntax("convertROtoRW", ConvertRO, 0, - "convert a RO volume into a RW volume (after loss of old RW volume)"); - cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); - cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name"); - cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID"); - 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 */ - if (cstruct) { - (void)ubik_ClientDestroy(cstruct); - cstruct = 0; - } - rx_Finalize(); - } - - exit((code ? -1 : 0)); -} diff --git a/src/volser/vos.rc b/src/volser/vos.rc deleted file mode 100644 index cc39de029..000000000 --- a/src/volser/vos.rc +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 - */ - -/* Define VERSIONINFO resource */ - -#define AFS_VERINFO_FILE_DESCRIPTION "AFS Volume Command" -#define AFS_VERINFO_NAME "vos" -#define AFS_VERINFO_FILENAME "vos.exe" - -#include "AFS_component_version_number.h" -#include "..\config\NTVersioninfo.rc" diff --git a/src/volser/vsprocs.c b/src/volser/vsprocs.c deleted file mode 100644 index 7faec4158..000000000 --- a/src/volser/vsprocs.c +++ /dev/null @@ -1,6880 +0,0 @@ -/* - * 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 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.30 2004/01/08 21:54:10 shadow Exp $"); - -#include -#include -#include -#ifdef AFS_AIX_ENV -#include -#endif -#ifdef AFS_NT40_ENV -#include -#include -#else -#include -#include -#endif - -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "volser.h" -#include "volint.h" -#include "lockdata.h" -#include -#include -#include -#include -#include -#define ERRCODE_RANGE 8 /* from error_table.h */ -#define CLOCKSKEW 2 /* not really skew, but resolution */ - -/* for UV_MoveVolume() recovery */ - -#include /* signal(), kill(), wait(), etc. */ -#include - -#include - -struct ubik_client *cstruct; -int verbose = 0; - -struct release { - afs_int32 time; - afs_int32 vldbEntryIndex; -}; - -/* Utility macros used by rest of this source file */ -#define EPRINT(ec, es) \ -do { \ - fprintf(STDERR, "\n"); \ - fprintf(STDERR, (es)); \ - PrintError(" ",ec); \ -} while (0) - -#define EPRINT1(ec, es, ep1) \ -do { \ - fprintf(STDERR, "\n"); \ - fprintf(STDERR, (es), (ep1)); \ - PrintError(" ",ec); \ -} while (0) - -#define EPRINT2(ec, es, ep1, ep2) \ -do { \ - fprintf(STDERR, "\n"); \ - fprintf(STDERR, (es), (ep1), (ep2)); \ - PrintError(" ",ec); \ -} while (0) - -#define EPRINT3(ec, es, ep1, ep2, ep3) \ -do { \ - fprintf(STDERR, "\n"); \ - fprintf(STDERR, (es), (ep1), (ep2), (ep3)); \ - PrintError(" ",ec); \ -} while (0) - -#define EGOTO(where, ec, es) \ -do { \ - if (ec) { \ - EPRINT((ec),(es)); \ - error = (ec); \ - goto where; \ - } \ -} while (0) - -#define EGOTO1(where, ec, es, ep1) \ -do { \ - if (ec) { \ - EPRINT1((ec),(es),(ep1)); \ - error = (ec); \ - goto where; \ - } \ -} while (0) - -#define EGOTO2(where, ec, es, ep1, ep2) \ -do { \ - if (ec) { \ - EPRINT2((ec),(es),(ep1),(ep2)); \ - error = (ec); \ - goto where; \ - } \ -} while (0) - -#define EGOTO3(where, ec, es, ep1, ep2, ep3) \ -do { \ - if (ec) { \ - EPRINT3((ec),(es),(ep1),(ep2),(ep3)); \ - error = (ec); \ - goto where; \ - } \ -} while (0) - -#define VPRINT(es) \ - { if (verbose) { fprintf(STDOUT, (es)); fflush(STDOUT); } } -#define VPRINT1(es, p) \ - { if (verbose) { fprintf(STDOUT, (es), (p)); fflush(STDOUT); } } -#define VPRINT2(es, p1, p2) \ - { if (verbose) { fprintf(STDOUT, (es), (p1), (p2)); fflush(STDOUT); } } -#define VPRINT3(es, p1, p2, p3) \ - { if (verbose) { fprintf(STDOUT, (es), (p1), (p2), (p3)); fflush(STDOUT); } } -#define VDONE \ - { if (verbose) { fprintf(STDOUT, " done\n"); fflush(STDOUT); } } - - - -/* getting rid of this */ -#define ERROR_EXIT(code) {error=(code); goto error_exit;} - - -/* Protos for static routines */ -static afs_int32 CheckAndDeleteVolume(struct rx_connection *aconn, - afs_int32 apart, afs_int32 okvol, - afs_int32 delvol); -static int DelVol(struct rx_connection *conn, afs_int32 vid, afs_int32 part, - afs_int32 flags); -static int GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index, - struct rx_connection **connPtr, afs_int32 * transPtr, - afs_int32 * timePtr); -static int SimulateForwardMultiple(struct rx_connection *fromconn, - afs_int32 fromtid, afs_int32 fromdate, - manyDests * tr, afs_int32 flags, - void *cookie, manyResults * results); -static int rel_compar(struct release *r1, struct release *r2); -static afs_int32 CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, - afs_int32 apart, afs_int32 * modentry, - afs_uint32 * maxvolid); - - -/*map the partition into partition name */ -void -MapPartIdIntoName(afs_int32 partId, char *partName) -{ - if (partId < 26) { /* what if partId > = 26 ? */ - strcpy(partName, "/vicep"); - partName[6] = partId + 'a'; - partName[7] = '\0'; - return; - } else if (partId < VOLMAXPARTS) { - strcpy(partName, "/vicep"); - partId -= 26; - partName[6] = 'a' + (partId / 26); - partName[7] = 'a' + (partId % 26); - partName[8] = '\0'; - return; - } -} - -int -yesprompt(char *str) -{ - int response, c; - int code; - - fprintf(STDERR, "Do you want to %s? [yn](n): ", str); - response = c = getchar(); - while (!(c == EOF || c == '\n')) - c = getchar(); /*skip to end of line */ - code = (response == 'y' || response == 'Y'); - return code; -} - - -int -PrintError(char *msg, afs_int32 errcode) -{ - fprintf(STDERR, msg); - /*replace by a big switch statement */ - switch (errcode) { - case 0: - break; - case -1: - fprintf(STDERR, "Possible communication failure\n"); - break; - case VSALVAGE: - fprintf(STDERR, "Volume needs to be salvaged\n"); - break; - case VNOVNODE: - fprintf(STDERR, "Bad vnode number quoted\n"); - break; - case VNOVOL: - fprintf(STDERR, - "Volume not attached, does not exist, or not on line\n"); - break; - case VVOLEXISTS: - fprintf(STDERR, "Volume already exists\n"); - break; - case VNOSERVICE: - fprintf(STDERR, "Volume is not in service\n"); - break; - case VOFFLINE: - fprintf(STDERR, "Volume is off line\n"); - break; - case VONLINE: - fprintf(STDERR, "Volume is already on line\n"); - break; - case VDISKFULL: - fprintf(STDERR, "Partition is full\n"); - break; - case VOVERQUOTA: - fprintf(STDERR, "Volume max quota exceeded\n"); - break; - case VBUSY: - fprintf(STDERR, "Volume temporarily unavailable\n"); - break; - case VMOVED: - fprintf(STDERR, "Volume has moved to another server\n"); - break; - case VL_IDEXIST: - fprintf(STDERR, "VLDB: volume Id exists in the vldb\n"); - break; - case VL_IO: - fprintf(STDERR, "VLDB: a read terminated too early\n"); - break; - case VL_NAMEEXIST: - fprintf(STDERR, "VLDB: volume entry exists in the vldb\n"); - break; - case VL_CREATEFAIL: - fprintf(STDERR, "VLDB: internal creation failure\n"); - break; - case VL_NOENT: - fprintf(STDERR, "VLDB: no such entry\n"); - break; - case VL_EMPTY: - fprintf(STDERR, "VLDB: vldb database is empty\n"); - break; - case VL_ENTDELETED: - fprintf(STDERR, "VLDB: entry is deleted (soft delete)\n"); - break; - case VL_BADNAME: - fprintf(STDERR, "VLDB: volume name is illegal\n"); - break; - case VL_BADINDEX: - fprintf(STDERR, "VLDB: index was out of range\n"); - break; - case VL_BADVOLTYPE: - fprintf(STDERR, "VLDB: bad volume type\n"); - break; - case VL_BADSERVER: - fprintf(STDERR, "VLDB: illegal server number (not within limits)\n"); - break; - case VL_BADPARTITION: - fprintf(STDERR, "VLDB: bad partition number\n"); - break; - case VL_REPSFULL: - fprintf(STDERR, "VLDB: run out of space for replication sites\n"); - break; - case VL_NOREPSERVER: - fprintf(STDERR, "VLDB: no such repsite server exists\n"); - break; - case VL_DUPREPSERVER: - fprintf(STDERR, "VLDB: replication site server already exists\n"); - break; - case VL_RWNOTFOUND: - fprintf(STDERR, "VLDB: parent r/w entry not found\n"); - break; - case VL_BADREFCOUNT: - fprintf(STDERR, "VLDB: illegal reference count number\n"); - break; - case VL_SIZEEXCEEDED: - fprintf(STDERR, "VLDB: vldb size for attributes exceeded\n"); - break; - case VL_BADENTRY: - fprintf(STDERR, "VLDB: bad incoming vldb entry\n"); - break; - case VL_BADVOLIDBUMP: - fprintf(STDERR, "VLDB: illegal max volid increment\n"); - break; - case VL_IDALREADYHASHED: - fprintf(STDERR, "VLDB: (RO/BACK) Id already hashed\n"); - break; - case VL_ENTRYLOCKED: - fprintf(STDERR, "VLDB: vldb entry is already locked\n"); - break; - case VL_BADVOLOPER: - fprintf(STDERR, "VLDB: bad volume operation code\n"); - break; - case VL_BADRELLOCKTYPE: - fprintf(STDERR, "VLDB: bad release lock type\n"); - break; - case VL_RERELEASE: - fprintf(STDERR, "VLDB: status report: last release was aborted\n"); - break; - case VL_BADSERVERFLAG: - fprintf(STDERR, "VLDB: invalid replication site server flag\n"); - break; - case VL_PERM: - fprintf(STDERR, "VLDB: no permission access for call\n"); - break; - case VOLSERREAD_DUMPERROR: - fprintf(STDERR, - "VOLSER: Problems encountered in reading the dump file !\n"); - break; - case VOLSERDUMPERROR: - fprintf(STDERR, "VOLSER: Problems encountered in doing the dump !\n"); - break; - case VOLSERATTACH_ERROR: - fprintf(STDERR, "VOLSER: Could not attach the volume\n"); - break; - case VOLSERDETACH_ERROR: - fprintf(STDERR, "VOLSER: Could not detach the volume\n"); - break; - case VOLSERILLEGAL_PARTITION: - fprintf(STDERR, "VOLSER: encountered illegal partition number\n"); - break; - case VOLSERBAD_ACCESS: - fprintf(STDERR, "VOLSER: permission denied, not a super user\n"); - break; - case VOLSERVLDB_ERROR: - fprintf(STDERR, "VOLSER: error detected in the VLDB\n"); - break; - case VOLSERBADNAME: - fprintf(STDERR, "VOLSER: error in volume name\n"); - break; - case VOLSERVOLMOVED: - fprintf(STDERR, "VOLSER: volume has moved\n"); - break; - case VOLSERBADOP: - fprintf(STDERR, "VOLSER: illegal operation\n"); - break; - case VOLSERBADRELEASE: - fprintf(STDERR, "VOLSER: release could not be completed\n"); - break; - case VOLSERVOLBUSY: - fprintf(STDERR, "VOLSER: volume is busy\n"); - break; - case VOLSERNO_MEMORY: - fprintf(STDERR, "VOLSER: volume server is out of memory\n"); - break; - case VOLSERNOVOL: - fprintf(STDERR, - "VOLSER: no such volume - location specified incorrectly or volume does not exist\n"); - break; - case VOLSERMULTIRWVOL: - fprintf(STDERR, - "VOLSER: multiple RW volumes with same ID, one of which should be deleted\n"); - break; - case VOLSERFAILEDOP: - fprintf(STDERR, - "VOLSER: not all entries were successfully processed\n"); - break; - default: - { - - afs_int32 offset; - - initialize_KA_error_table(); - initialize_RXK_error_table(); - initialize_KTC_error_table(); - initialize_ACFG_error_table(); - initialize_CMD_error_table(); - initialize_VL_error_table(); - - offset = errcode & ((1 << ERRCODE_RANGE) - 1); - fprintf(STDERR, "%s: %s\n", error_table_name(errcode), - error_message(errcode)); - break; - } - } - return 0; -} - - -static struct rx_securityClass *uvclass = 0; -static int uvindex = -1; -/* called by VLDBClient_Init to set the security module to be used in the RPC */ -int -UV_SetSecurity(register struct rx_securityClass *as, afs_int32 aindex) -{ - uvindex = aindex; - uvclass = as; - return 0; -} - -/* bind to volser on */ -/* takes server address in network order, port in host order. dumb */ -struct rx_connection * -UV_Bind(afs_int32 aserver, afs_int32 port) -{ - register struct rx_connection *tc; - - tc = rx_NewConnection(aserver, htons(port), VOLSERVICE_ID, uvclass, - uvindex); - return tc; -} - -/* if is allright(indicated by beibg able to - * start a transaction, delete the */ -static afs_int32 -CheckAndDeleteVolume(struct rx_connection *aconn, afs_int32 apart, - afs_int32 okvol, afs_int32 delvol) -{ - afs_int32 error, code, tid, rcode; - - error = 0; - code = 0; - - if (okvol == 0) { - code = AFSVolTransCreate(aconn, delvol, apart, ITOffline, &tid); - if (!error && code) - error = code; - code = AFSVolDeleteVolume(aconn, tid); - if (!error && code) - error = code; - code = AFSVolEndTrans(aconn, tid, &rcode); - if (!code) - code = rcode; - if (!error && code) - error = code; - return error; - } else { - code = AFSVolTransCreate(aconn, okvol, apart, ITOffline, &tid); - if (!code) { - code = AFSVolEndTrans(aconn, tid, &rcode); - if (!code) - code = rcode; - if (!error && code) - error = code; - code = AFSVolTransCreate(aconn, delvol, apart, ITOffline, &tid); - if (!error && code) - error = code; - code = AFSVolDeleteVolume(aconn, tid); - if (!error && code) - error = code; - code = AFSVolEndTrans(aconn, tid, &rcode); - if (!code) - code = rcode; - if (!error && code) - error = code; - } else - error = code; - return error; - } -} - -/* called by EmuerateEntry, show vldb entry in a reasonable format */ -void -SubEnumerateEntry(struct nvldbentry *entry) -{ - int i; - char pname[10]; - int isMixed = 0; - -#ifdef notdef - fprintf(STDOUT, " readWriteID %-10u ", entry->volumeId[RWVOL]); - if (entry->flags & RW_EXISTS) - fprintf(STDOUT, " valid \n"); - else - fprintf(STDOUT, " invalid \n"); - fprintf(STDOUT, " readOnlyID %-10u ", entry->volumeId[ROVOL]); - if (entry->flags & RO_EXISTS) - fprintf(STDOUT, " valid \n"); - else - fprintf(STDOUT, " invalid \n"); - fprintf(STDOUT, " backUpID %-10u ", entry->volumeId[BACKVOL]); - if (entry->flags & BACK_EXISTS) - fprintf(STDOUT, " valid \n"); - else - fprintf(STDOUT, " invalid \n"); - if ((entry->cloneId != 0) && (entry->flags & RO_EXISTS)) - fprintf(STDOUT, " releaseClone %-10u \n", entry->cloneId); -#else - if (entry->flags & RW_EXISTS) - fprintf(STDOUT, " RWrite: %-10u", entry->volumeId[RWVOL]); - if (entry->flags & RO_EXISTS) - fprintf(STDOUT, " ROnly: %-10u", entry->volumeId[ROVOL]); - if (entry->flags & BACK_EXISTS) - fprintf(STDOUT, " Backup: %-10u", entry->volumeId[BACKVOL]); - if ((entry->cloneId != 0) && (entry->flags & RO_EXISTS)) - fprintf(STDOUT, " RClone: %-10lu", (unsigned long)entry->cloneId); - fprintf(STDOUT, "\n"); -#endif - fprintf(STDOUT, " number of sites -> %lu\n", - (unsigned long)entry->nServers); - for (i = 0; i < entry->nServers; i++) { - if (entry->serverFlags[i] & NEW_REPSITE) - isMixed = 1; - } - for (i = 0; i < entry->nServers; i++) { - MapPartIdIntoName(entry->serverPartition[i], pname); - fprintf(STDOUT, " server %s partition %s ", - hostutil_GetNameByINet(entry->serverNumber[i]), pname); - if (entry->serverFlags[i] & ITSRWVOL) - fprintf(STDOUT, "RW Site "); - else - fprintf(STDOUT, "RO Site "); - if (isMixed) { - if (entry->serverFlags[i] & NEW_REPSITE) - fprintf(STDOUT, " -- New release"); - else - fprintf(STDOUT, " -- Old release"); - } else { - if (entry->serverFlags[i] & RO_DONTUSE) - fprintf(STDOUT, " -- Not released"); - } - fprintf(STDOUT, "\n"); - } - - return; - -} - -/*enumerate the vldb entry corresponding to */ -void -EnumerateEntry(struct nvldbentry *entry) -{ - - fprintf(STDOUT, "\n"); - fprintf(STDOUT, "%s \n", entry->name); - SubEnumerateEntry(entry); - return; -} - -/* forcibly remove a volume. Very dangerous call */ -int -UV_NukeVolume(afs_int32 server, afs_int32 partid, afs_int32 volid) -{ - register struct rx_connection *tconn; - register afs_int32 code; - - tconn = UV_Bind(server, AFSCONF_VOLUMEPORT); - if (tconn) { - code = AFSVolNukeVolume(tconn, partid, volid); - rx_DestroyConnection(tconn); - } else - code = 0; - return code; -} - -/* like df. Return usage of on in */ -int -UV_PartitionInfo(afs_int32 server, char *pname, - struct diskPartition *partition) -{ - register struct rx_connection *aconn; - afs_int32 code; - - code = 0; - aconn = (struct rx_connection *)0; - aconn = UV_Bind(server, AFSCONF_VOLUMEPORT); - code = AFSVolPartitionInfo(aconn, pname, partition); - if (code) { - fprintf(STDERR, "Could not get information on partition %s\n", pname); - PrintError("", code); - } - if (aconn) - rx_DestroyConnection(aconn); - return code; -} - -/* old interface to create volume */ -int -UV_CreateVolume(afs_int32 aserver, afs_int32 apart, char *aname, - afs_int32 * anewid) -{ - afs_int32 code; - code = UV_CreateVolume2(aserver, apart, aname, 5000, 0, 0, 0, 0, anewid); - return code; -} - -/* create a volume, given a server, partition number, volume name --> sends -* back new vol id in */ -int -UV_CreateVolume2(afs_int32 aserver, afs_int32 apart, char *aname, - afs_int32 aquota, afs_int32 aspare1, afs_int32 aspare2, - afs_int32 aspare3, afs_int32 aspare4, afs_int32 * anewid) -{ - - register struct rx_connection *aconn; - afs_int32 tid; - register afs_int32 code; - afs_int32 error; - afs_int32 rcode, vcode; - struct nvldbentry entry, storeEntry; /*the new vldb entry */ - struct volintInfo tstatus; - - tid = 0; - aconn = (struct rx_connection *)0; - error = 0; - memset(&tstatus, 0, sizeof(struct volintInfo)); - tstatus.dayUse = -1; - tstatus.maxquota = aquota; - - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - /* next the next 3 available ids from the VLDB */ - vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 3, anewid); - EGOTO1(cfail, vcode, "Could not get an Id for volume %s\n", aname); - - code = - AFSVolCreateVolume(aconn, apart, aname, volser_RW, 0, anewid, &tid); - EGOTO2(cfail, vcode, "Failed to create the volume %s %u \n", aname, - *anewid); - - code = AFSVolSetInfo(aconn, tid, &tstatus); - if (code) - EPRINT(code, "Could not change quota (error %d), continuing...\n"); - - code = AFSVolSetFlags(aconn, tid, 0); /* bring it online (mark it InService */ - EGOTO2(cfail, vcode, "Could not bring the volume %s %u online \n", aname, - *anewid); - - VPRINT2("Volume %s %u created and brought online\n", aname, *anewid); - - /* set up the vldb entry for this volume */ - strncpy(entry.name, aname, VOLSER_OLDMAXVOLNAME); - entry.nServers = 1; - entry.serverNumber[0] = aserver; /* this should have another - * level of indirection later */ - entry.serverPartition[0] = apart; /* this should also have - * another indirection level */ - entry.flags = RW_EXISTS; /* this records that rw volume exists */ - entry.serverFlags[0] = ITSRWVOL; /*this rep site has rw vol */ - entry.volumeId[RWVOL] = *anewid; - entry.volumeId[ROVOL] = *anewid + 1; /* rw,ro, bk id are related in the default case */ - entry.volumeId[BACKVOL] = *anewid + 2; - entry.cloneId = 0; - /*map into right byte order, before passing to xdr, the stuff has to be in host - * byte order. Xdr converts it into network order */ - MapNetworkToHost(&entry, &storeEntry); - /* create the vldb entry */ - vcode = VLDB_CreateEntry(&storeEntry); - if (vcode) { - fprintf(STDERR, - "Could not create a VLDB entry for the volume %s %lu\n", - aname, (unsigned long)*anewid); - /*destroy the created volume */ - VPRINT1("Deleting the newly created volume %u\n", *anewid); - AFSVolDeleteVolume(aconn, tid); - error = vcode; - goto cfail; - } - VPRINT2("Created the VLDB entry for the volume %s %u\n", aname, *anewid); - /* volume created, now terminate the transaction and release the connection */ - code = AFSVolEndTrans(aconn, tid, &rcode); /*if it crashes before this - * the volume will come online anyway when transaction timesout , so if - * vldb entry exists then the volume is guaranteed to exist too wrt create */ - tid = 0; - if (code) { - fprintf(STDERR, - "Failed to end the transaction on the volume %s %lu\n", aname, - (unsigned long)*anewid); - error = code; - goto cfail; - } - - cfail: - if (tid) { - code = AFSVolEndTrans(aconn, tid, &rcode); - if (code) - fprintf(STDERR, "WARNING: could not end transaction\n"); - } - if (aconn) - rx_DestroyConnection(aconn); - PrintError("", error); - return error; - - -} - -/* create a volume, given a server, partition number, volume name --> sends -* back new vol id in */ -int -UV_AddVLDBEntry(afs_int32 aserver, afs_int32 apart, char *aname, - afs_int32 aid) -{ - register struct rx_connection *aconn; - afs_int32 error; - afs_int32 vcode; - struct nvldbentry entry, storeEntry; /*the new vldb entry */ - - aconn = (struct rx_connection *)0; - error = 0; - - /* set up the vldb entry for this volume */ - strncpy(entry.name, aname, VOLSER_OLDMAXVOLNAME); - entry.nServers = 1; - entry.serverNumber[0] = aserver; /* this should have another - * level of indirection later */ - entry.serverPartition[0] = apart; /* this should also have - * another indirection level */ - entry.flags = RW_EXISTS; /* this records that rw volume exists */ - entry.serverFlags[0] = ITSRWVOL; /*this rep site has rw vol */ - entry.volumeId[RWVOL] = aid; -#ifdef notdef - entry.volumeId[ROVOL] = anewid + 1; /* rw,ro, bk id are related in the default case */ - entry.volumeId[BACKVOL] = *anewid + 2; -#else - entry.volumeId[ROVOL] = 0; - entry.volumeId[BACKVOL] = 0; -#endif - entry.cloneId = 0; - /*map into right byte order, before passing to xdr, the stuff has to be in host - * byte order. Xdr converts it into network order */ - MapNetworkToHost(&entry, &storeEntry); - /* create the vldb entry */ - vcode = VLDB_CreateEntry(&storeEntry); - if (vcode) { - fprintf(STDERR, - "Could not create a VLDB entry for the volume %s %lu\n", - aname, (unsigned long)aid); - error = vcode; - goto cfail; - } - VPRINT2("Created the VLDB entry for the volume %s %u\n", aname, aid); - - cfail: - if (aconn) - rx_DestroyConnection(aconn); - PrintError("", error); - return error; -} - -/* Delete the volume on - * the physical entry gets removed from the vldb only if the ref count - * becomes zero - */ -int -UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid) -{ - struct rx_connection *aconn = (struct rx_connection *)0; - afs_int32 ttid = 0; - afs_int32 code, rcode; - afs_int32 error = 0; - struct nvldbentry entry, storeEntry; - int islocked = 0; - afs_int32 avoltype = -1, vtype; - int notondisk = 0, notinvldb = 0; - - /* Find and read bhe VLDB entry for this volume */ - code = ubik_Call(VL_SetLock, cstruct, 0, avolid, avoltype, VLOP_DELETE); - if (code) { - if (code != VL_NOENT) { - EGOTO1(error_exit, code, - "Could not lock VLDB entry for the volume %u\n", avolid); - } - notinvldb = 1; - } else { - islocked = 1; - - code = VLDB_GetEntryByID(avolid, avoltype, &entry); - EGOTO1(error_exit, code, "Could not fetch VLDB entry for volume %u\n", - avolid); - MapHostToNetwork(&entry); - - if (verbose) - EnumerateEntry(&entry); - } - - /* Whether volume is in the VLDB or not. Delete the volume on disk */ - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - code = AFSVolTransCreate(aconn, avolid, apart, ITOffline, &ttid); - if (code) { - if (code == VNOVOL) { - notondisk = 1; - } else { - EGOTO1(error_exit, code, "Transaction on volume %u failed\n", - avolid); - } - } else { - VPRINT1("Trying to delete the volume %u ...", avolid); - - code = AFSVolDeleteVolume(aconn, ttid); - EGOTO1(error_exit, code, "Could not delete the volume %u \n", avolid); - - code = AFSVolEndTrans(aconn, ttid, &rcode); - code = (code ? code : rcode); - ttid = 0; - EGOTO1(error_exit, code, - "Could not end the transaction for the volume %u \n", avolid); - VDONE; - } - - /* Now update the VLDB entry. - * But first, verify we have a VLDB entry. - * Whether volume is on disk or not. Delete the volume in VLDB. - */ - if (notinvldb) - ERROR_EXIT(0); - - if (avolid == entry.volumeId[BACKVOL]) { - /* Its a backup volume, modify the VLDB entry. Check that the - * backup volume is on the server/partition we asked to delete. - */ - if (!(entry.flags & BACK_EXISTS) || !Lp_Match(aserver, apart, &entry)) { - notinvldb = 2; /* Not on this server and partition */ - ERROR_EXIT(0); - } - - VPRINT1("Marking the backup volume %u deleted in the VLDB\n", avolid); - - entry.flags &= ~BACK_EXISTS; - vtype = BACKVOL; - } - - else if (avolid == entry.volumeId[ROVOL]) { - /* Its a read-only volume, modify the VLDB entry. Check that the - * readonly volume is on the server/partition we asked to delete. - * If flags does not have RO_EIXSTS set, then this may mean the RO - * hasn't been released (and could exist in VLDB). - */ - if (!Lp_ROMatch(aserver, apart, &entry)) { - notinvldb = 2; /* Not found on this server and partition */ - ERROR_EXIT(0); - } - - if (verbose) - fprintf(STDOUT, - "Marking the readonly volume %lu deleted in the VLDB\n", - (unsigned long)avolid); - - Lp_SetROValue(&entry, aserver, apart, 0, 0); /* delete the site */ - entry.nServers--; - if (!Lp_ROMatch(0, 0, &entry)) - entry.flags &= ~RO_EXISTS; /* This was the last ro volume */ - vtype = ROVOL; - } - - else if (avolid == entry.volumeId[RWVOL]) { - /* It's a rw volume, delete the backup volume, modify the VLDB entry. - * Check that the readwrite volumes is on the server/partition we - * asked to delete. - */ - if (!(entry.flags & RW_EXISTS) || !Lp_Match(aserver, apart, &entry)) { - notinvldb = 2; /* Not found on this server and partition */ - ERROR_EXIT(0); - } - - /* Delete backup if it exists */ - code = - AFSVolTransCreate(aconn, entry.volumeId[BACKVOL], apart, - ITOffline, &ttid); - if (!code) { - if (verbose) { - fprintf(STDOUT, "Trying to delete the backup volume %u ...", - entry.volumeId[BACKVOL]); - fflush(STDOUT); - } - code = AFSVolDeleteVolume(aconn, ttid); - EGOTO1(error_exit, code, "Could not delete the volume %u \n", - entry.volumeId[BACKVOL]); - - code = AFSVolEndTrans(aconn, ttid, &rcode); - ttid = 0; - code = (code ? code : rcode); - EGOTO1(error_exit, code, - "Could not end the transaction for the volume %u \n", - entry.volumeId[BACKVOL]); - if (verbose) - fprintf(STDOUT, " done\n"); - } - - if (verbose) - fprintf(STDOUT, - "Marking the readwrite volume %lu%s deleted in the VLDB\n", - (unsigned long)avolid, - ((entry. - flags & BACK_EXISTS) ? ", and its backup volume," : - "")); - - Lp_SetRWValue(&entry, aserver, apart, 0L, 0L); - entry.nServers--; - entry.flags &= ~(BACK_EXISTS | RW_EXISTS); - vtype = RWVOL; - - if (entry.flags & RO_EXISTS) - fprintf(STDERR, "WARNING: ReadOnly copy(s) may still exist\n"); - } - - else { - notinvldb = 2; /* Not found on this server and partition */ - ERROR_EXIT(0); - } - - /* Either delete or replace the VLDB entry */ - if ((entry.nServers <= 0) || !(entry.flags & (RO_EXISTS | RW_EXISTS))) { - if (verbose) - fprintf(STDOUT, - "Last reference to the VLDB entry for %lu - deleting entry\n", - (unsigned long)avolid); - code = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, vtype); - EGOTO1(error_exit, code, - "Could not delete the VLDB entry for the volume %u \n", - avolid); - } else { - MapNetworkToHost(&entry, &storeEntry); - code = - VLDB_ReplaceEntry(avolid, vtype, &storeEntry, - (LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP)); - EGOTO1(error_exit, code, - "Could not update the VLDB entry for the volume %u \n", - avolid); - } - islocked = 0; - - error_exit: - if (error) - EPRINT(error, "\n"); - - if (notondisk && notinvldb) { - EPRINT2(VOLSERNOVOL, "Volume %u does not exist %s\n", avolid, - ((notinvldb == 2) ? "on server and partition" : "")); - if (!error) - error = VOLSERNOVOL; - } else if (notondisk) { - fprintf(STDERR, - "WARNING: Volume %lu did not exist on the partition\n", - (unsigned long)avolid); - } else if (notinvldb) { - fprintf(STDERR, "WARNING: Volume %lu does not exist in VLDB %s\n", - (unsigned long)avolid, - ((notinvldb == 2) ? "on server and partition" : "")); - } - - if (ttid) { - code = AFSVolEndTrans(aconn, ttid, &rcode); - code = (code ? code : rcode); - if (code) { - fprintf(STDERR, "Could not end transaction on the volume %lu\n", - (unsigned long)avolid); - PrintError("", code); - if (!error) - error = code; - } - } - - if (islocked) { - code = - ubik_Call(VL_ReleaseLock, cstruct, 0, avolid, -1, - (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP)); - if (code) { - EPRINT1(code, - "Could not release the lock on the VLDB entry for the volume %u \n", - avolid); - if (!error) - error = code; - } - } - - if (aconn) - rx_DestroyConnection(aconn); - return error; -} - -/* add recovery to UV_MoveVolume */ - -#define TESTC 0 /* set to test recovery code, clear for production */ - -jmp_buf env; -int interrupt = 0; - -void -sigint_handler(int x) -{ - if (interrupt) - longjmp(env, 0); - - fprintf(STDOUT, "\nSIGINT handler: vos move operation in progress\n"); - fprintf(STDOUT, - "WARNING: may leave AFS storage and metadata in indeterminate state\n"); - fprintf(STDOUT, "enter second control-c to exit\n"); - fflush(STDOUT); - - interrupt = 1; - (void)signal(SIGINT, sigint_handler); - - return; -} - -/* Move volume on to - * . The operation is almost idempotent. The following - * flags are recognized: - * - * RV_NOCLONE - don't use a copy clone - */ - -int -UV_MoveVolume2(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart, - afs_int32 atoserver, afs_int32 atopart, int flags) -{ - struct rx_connection *toconn, *fromconn; - afs_int32 fromtid, totid, clonetid; - char vname[64]; - char *volName = 0; - char tmpName[VOLSER_MAXVOLNAME + 1]; - afs_int32 rcode; - afs_int32 fromDate; - struct restoreCookie cookie; - register afs_int32 vcode, code; - afs_int32 newVol, volid, backupId; - struct volser_status tstatus; - struct destServer destination; - - struct nvldbentry entry, storeEntry; - int i, islocked, pntg; - afs_int32 error; - char in, lf; /* for test code */ - int same; - -#ifdef ENABLE_BUGFIX_1165 - volEntries volumeInfo; - struct volintInfo *infop = 0; -#endif - - islocked = 0; - fromconn = (struct rx_connection *)0; - toconn = (struct rx_connection *)0; - fromtid = 0; - totid = 0; - clonetid = 0; - error = 0; - volid = 0; - pntg = 0; - backupId = 0; - newVol = 0; - - /* support control-c processing */ - if (setjmp(env)) - goto mfail; - (void)signal(SIGINT, sigint_handler); - - if (TESTC) { - fprintf(STDOUT, - "\nThere are three tests points - verifies all code paths through recovery.\n"); - fprintf(STDOUT, "First test point - operation not started.\n"); - fprintf(STDOUT, "...test here (y, n)? "); - fflush(STDOUT); - fscanf(stdin, "%c", &in); - fscanf(stdin, "%c", &lf); /* toss away */ - if (in == 'y') { - fprintf(STDOUT, "type control-c\n"); - while (1) { - fprintf(stdout, "."); - fflush(stdout); - sleep(1); - } - } - /* or drop through */ - } - - vcode = VLDB_GetEntryByID(afromvol, -1, &entry); - EGOTO1(mfail, vcode, - "Could not fetch the entry for the volume %u from the VLDB \n", - afromvol); - - if (entry.volumeId[RWVOL] != afromvol) { - fprintf(STDERR, "Only RW volume can be moved\n"); - exit(1); - } - - vcode = ubik_Call(VL_SetLock, cstruct, 0, afromvol, RWVOL, VLOP_MOVE); - EGOTO1(mfail, vcode, "Could not lock entry for volume %u \n", afromvol); - islocked = 1; - - vcode = VLDB_GetEntryByID(afromvol, RWVOL, &entry); - EGOTO1(mfail, vcode, - "Could not fetch the entry for the volume %u from the VLDB \n", - afromvol); - - backupId = entry.volumeId[BACKVOL]; - MapHostToNetwork(&entry); - - if (!Lp_Match(afromserver, afrompart, &entry)) { - /* the from server and partition do not exist in the vldb entry corresponding to volid */ - if (!Lp_Match(atoserver, atopart, &entry)) { - /* the to server and partition do not exist in the vldb entry corresponding to volid */ - fprintf(STDERR, "The volume %lu is not on the specified site. \n", - (unsigned long)afromvol); - fprintf(STDERR, "The current site is :"); - for (i = 0; i < entry.nServers; i++) { - if (entry.serverFlags[i] == ITSRWVOL) { - char pname[10]; - MapPartIdIntoName(entry.serverPartition[i], pname); - fprintf(STDERR, " server %s partition %s \n", - hostutil_GetNameByINet(entry.serverNumber[i]), - pname); - } - } - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1, - (LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP)); - EGOTO1(mfail, vcode, - " Could not release lock on the VLDB entry for the volume %u \n", - afromvol); - - return VOLSERVOLMOVED; - } - - /* delete the volume afromvol on src_server */ - /* from-info does not exist but to-info does => - * we have already done the move, but the volume - * may still be existing physically on from fileserver - */ - fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT); - fromtid = 0; - pntg = 1; - - code = - AFSVolTransCreate(fromconn, afromvol, afrompart, ITOffline, - &fromtid); - if (!code) { /* volume exists - delete it */ - VPRINT1("Setting flags on leftover source volume %u ...", - afromvol); - code = - AFSVolSetFlags(fromconn, fromtid, - VTDeleteOnSalvage | VTOutOfService); - EGOTO1(mfail, code, - "Failed to set flags on the leftover source volume %u\n", - afromvol); - VDONE; - - VPRINT1("Deleting leftover source volume %u ...", afromvol); - code = AFSVolDeleteVolume(fromconn, fromtid); - EGOTO1(mfail, code, - "Failed to delete the leftover source volume %u\n", - afromvol); - VDONE; - - VPRINT1("Ending transaction on leftover source volume %u ...", - afromvol); - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Could not end the transaction for the leftover source volume %u \n", - afromvol); - VDONE; - } - - /*delete the backup volume now */ - fromtid = 0; - code = - AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline, - &fromtid); - if (!code) { /* backup volume exists - delete it */ - VPRINT1("Setting flags on leftover backup volume %u ...", - backupId); - code = - AFSVolSetFlags(fromconn, fromtid, - VTDeleteOnSalvage | VTOutOfService); - EGOTO1(mfail, code, - "Failed to set flags on the backup volume %u\n", backupId); - VDONE; - - VPRINT1("Deleting leftover backup volume %u ...", backupId); - code = AFSVolDeleteVolume(fromconn, fromtid); - EGOTO1(mfail, code, - "Could not delete the leftover backup volume %u\n", - backupId); - VDONE; - - VPRINT1("Ending transaction on leftover backup volume %u ...", - backupId); - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Could not end the transaction for the leftover backup volume %u\n", - backupId); - VDONE; - } - - fromtid = 0; - error = 0; - goto mfail; - } - - /* From-info matches the vldb info about volid, - * its ok start the move operation, the backup volume - * on the old site is deleted in the process - */ - if (afrompart == atopart) { - same = VLDB_IsSameAddrs(afromserver, atoserver, &error); - EGOTO2(mfail, error, - "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n", - afromserver, error); - - if (same) { - EGOTO1(mfail, VOLSERVOLMOVED, - "Warning: Moving volume %u to its home partition ignored!\n", - afromvol); - } - } - - pntg = 1; - toconn = UV_Bind(atoserver, AFSCONF_VOLUMEPORT); /* get connections to the servers */ - fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT); - fromtid = totid = 0; /* initialize to uncreated */ - - /* *** - * clone the read/write volume locally. - * ***/ - - VPRINT1("Starting transaction on source volume %u ...", afromvol); - code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid); - EGOTO1(mfail, code, "Failed to create transaction on the volume %u\n", - afromvol); - VDONE; - - if (!(flags & RV_NOCLONE)) { - /* Get a clone id */ - VPRINT1("Allocating new volume id for clone of volume %u ...", - afromvol); - newVol = 0; - vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &newVol); - EGOTO1(mfail, vcode, - "Could not get an ID for the clone of volume %u from the VLDB\n", - afromvol); - VDONE; - - /* Do the clone. Default flags on clone are set to delete on salvage and out of service */ - VPRINT1("Cloning source volume %u ...", afromvol); - strcpy(vname, "move-clone-temp"); - code = - AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &newVol); - EGOTO1(mfail, code, "Failed to clone the source volume %u\n", - afromvol); - VDONE; - } - - /* lookup the name of the volume we just cloned */ - volid = afromvol; - code = AFSVolGetName(fromconn, fromtid, &volName); - EGOTO1(mfail, code, "Failed to get the name of the volume %u\n", - afromvol); - - VPRINT1("Ending the transaction on the source volume %u ...", afromvol); - rcode = 0; - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Failed to end the transaction on the source volume %u\n", - afromvol); - VDONE; - - /* *** - * Create the destination volume - * ***/ - - if (!(flags & RV_NOCLONE)) { - /* All of this is to get the fromDate */ - VPRINT1("Starting transaction on the cloned volume %u ...", newVol); - code = - AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline, - &clonetid); - EGOTO1(mfail, code, - "Failed to start a transaction on the cloned volume%u\n", - newVol); - VDONE; - - VPRINT1("Setting flags on cloned volume %u ...", newVol); - code = - AFSVolSetFlags(fromconn, clonetid, - VTDeleteOnSalvage | VTOutOfService); /*redundant */ - EGOTO1(mfail, code, "Could not set flags on the cloned volume %u\n", - newVol); - VDONE; - - /* remember time from which we've dumped the volume */ - VPRINT1("Getting status of cloned volume %u ...", newVol); - code = AFSVolGetStatus(fromconn, clonetid, &tstatus); - EGOTO1(mfail, code, - "Failed to get the status of the cloned volume %u\n", - newVol); - VDONE; - - fromDate = tstatus.creationDate - CLOCKSKEW; - } else { - /* With RV_NOCLONE, just do a full copy from the source */ - fromDate = 0; - } - - -#ifdef ENABLE_BUGFIX_1165 - /* - * Get the internal volume state from the source volume. We'll use such info (i.e. dayUse) - * to copy it to the new volume (via AFSSetInfo later on) so that when we move volumes we - * don't use this information... - */ - volumeInfo.volEntries_val = (volintInfo *) 0; /*this hints the stub to allocate space */ - volumeInfo.volEntries_len = 0; - code = AFSVolListOneVolume(fromconn, afrompart, afromvol, &volumeInfo); - EGOTO1(mfail, code, - "Failed to get the volint Info of the cloned volume %u\n", - afromvol); - - infop = (volintInfo *) volumeInfo.volEntries_val; - infop->maxquota = -1; /* Else it will replace the default quota */ -#endif - - /* create a volume on the target machine */ - volid = afromvol; - code = AFSVolTransCreate(toconn, volid, atopart, ITOffline, &totid); - if (!code) { - /* Delete the existing volume. - * While we are deleting the volume in these steps, the transaction - * we started against the cloned volume (clonetid above) will be - * sitting idle. It will get cleaned up after 600 seconds - */ - VPRINT1("Deleting pre-existing volume %u on destination ...", volid); - code = AFSVolDeleteVolume(toconn, totid); - EGOTO1(mfail, code, - "Could not delete the pre-existing volume %u on destination\n", - volid); - VDONE; - - VPRINT1 - ("Ending transaction on pre-existing volume %u on destination ...", - volid); - code = AFSVolEndTrans(toconn, totid, &rcode); - totid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Could not end the transaction on pre-existing volume %u on destination\n", - volid); - VDONE; - } - - VPRINT1("Creating the destination volume %u ...", volid); - code = - AFSVolCreateVolume(toconn, atopart, volName, volser_RW, volid, &volid, - &totid); - EGOTO1(mfail, code, "Failed to create the destination volume %u\n", - volid); - VDONE; - - strncpy(tmpName, volName, VOLSER_OLDMAXVOLNAME); - free(volName); - volName = NULL; - - VPRINT1("Setting volume flags on destination volume %u ...", volid); - code = - AFSVolSetFlags(toconn, totid, (VTDeleteOnSalvage | VTOutOfService)); - EGOTO1(mfail, code, - "Failed to set the flags on the destination volume %u\n", volid); - VDONE; - - /*** - * Now dump the clone to the new volume - ***/ - - destination.destHost = ntohl(atoserver); - destination.destPort = AFSCONF_VOLUMEPORT; - destination.destSSID = 1; - - strncpy(cookie.name, tmpName, VOLSER_OLDMAXVOLNAME); - cookie.type = RWVOL; - cookie.parent = entry.volumeId[RWVOL]; - cookie.clone = 0; - - if (!(flags & RV_NOCLONE)) { - /* Copy the clone to the new volume */ - VPRINT2("Dumping from clone %u on source to volume %u on destination ...", - newVol, afromvol); - code = - AFSVolForward(fromconn, clonetid, 0, &destination, totid, - &cookie); - EGOTO1(mfail, code, "Failed to move data for the volume %u\n", volid); - VDONE; - - VPRINT1("Ending transaction on cloned volume %u ...", newVol); - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - if (!code) - code = rcode; - clonetid = 0; - EGOTO1(mfail, code, - "Failed to end the transaction on the cloned volume %u\n", - newVol); - VDONE; - } - - /* *** - * reattach to the main-line volume, and incrementally dump it. - * ***/ - - VPRINT1("Starting transaction on source volume %u ...", afromvol); - code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid); - EGOTO1(mfail, code, - "Failed to create a transaction on the source volume %u\n", - afromvol); - VDONE; - - /* now do the incremental */ - VPRINT2 - ("Doing the%s dump from source to destination for volume %u ... ", - (flags & RV_NOCLONE) ? "" : " incremental", - afromvol); - code = - AFSVolForward(fromconn, fromtid, fromDate, &destination, totid, - &cookie); - EGOTO1(mfail, code, - "Failed to do the%s dump from rw volume on old site to rw volume on newsite\n", - (flags & RV_NOCLONE) ? "" : " incremental"); - VDONE; - - /* now adjust the flags so that the new volume becomes official */ - VPRINT1("Setting volume flags on old source volume %u ...", afromvol); - code = AFSVolSetFlags(fromconn, fromtid, VTOutOfService); - EGOTO(mfail, code, - "Failed to set the flags to make old source volume offline\n"); - VDONE; - - VPRINT1("Setting volume flags on new source volume %u ...", afromvol); - code = AFSVolSetFlags(toconn, totid, 0); - EGOTO(mfail, code, - "Failed to set the flags to make new source volume online\n"); - VDONE; - -#ifdef ENABLE_BUGFIX_1165 - VPRINT1("Setting volume status on destination volume %u ...", volid); - code = AFSVolSetInfo(toconn, totid, infop); - EGOTO1(mfail, code, - "Failed to set volume status on the destination volume %u\n", - volid); - VDONE; -#endif - - /* put new volume online */ - VPRINT1("Ending transaction on destination volume %u ...", afromvol); - code = AFSVolEndTrans(toconn, totid, &rcode); - totid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Failed to end the transaction on the volume %u on the new site\n", - afromvol); - VDONE; - - Lp_SetRWValue(&entry, afromserver, afrompart, atoserver, atopart); - MapNetworkToHost(&entry, &storeEntry); - storeEntry.flags &= ~BACK_EXISTS; - - if (TESTC) { - fprintf(STDOUT, - "Second test point - operation in progress but not complete.\n"); - fprintf(STDOUT, "...test here (y, n)? "); - fflush(STDOUT); - fscanf(stdin, "%c", &in); - fscanf(stdin, "%c", &lf); /* toss away */ - if (in == 'y') { - fprintf(STDOUT, "type control-c\n"); - while (1) { - fprintf(stdout, "."); - fflush(stdout); - sleep(1); - } - } - /* or drop through */ - } - - VPRINT1("Releasing lock on VLDB entry for volume %u ...", afromvol); - vcode = - VLDB_ReplaceEntry(afromvol, -1, &storeEntry, - (LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP)); - if (vcode) { - fprintf(STDERR, - " Could not release the lock on the VLDB entry for the volume %s %lu \n", - storeEntry.name, (unsigned long)afromvol); - error = vcode; - goto mfail; - } - islocked = 0; - VDONE; - - if (TESTC) { - fprintf(STDOUT, - "Third test point - operation complete but no cleanup.\n"); - fprintf(STDOUT, "...test here (y, n)? "); - fflush(STDOUT); - fscanf(stdin, "%c", &in); - fscanf(stdin, "%c", &lf); /* toss away */ - if (in == 'y') { - fprintf(STDOUT, "type control-c\n"); - while (1) { - fprintf(stdout, "."); - fflush(stdout); - sleep(1); - } - } - /* or drop through */ - } -#ifdef notdef - /* This is tricky. File server is very stupid, and if you mark the volume - * as VTOutOfService, it may mark the *good* instance (if you're moving - * between partitions on the same machine) as out of service. Since - * we're cleaning this code up in DEcorum, we're just going to kludge around - * it for now by removing this call. */ - /* already out of service, just zap it now */ - code = - AFSVolSetFlags(fromconn, fromtid, VTDeleteOnSalvage | VTOutOfService); - if (code) { - fprintf(STDERR, - "Failed to set the flags to make the old source volume offline\n"); - goto mfail; - } -#endif - if (atoserver != afromserver) { - /* set forwarding pointer for moved volumes */ - VPRINT1("Setting forwarding pointer for volume %u ...", afromvol); - code = AFSVolSetForwarding(fromconn, fromtid, atoserver); - EGOTO1(mfail, code, - "Failed to set the forwarding pointer for the volume %u\n", - afromvol); - VDONE; - } - - VPRINT1("Deleting old volume %u on source ...", afromvol); - code = AFSVolDeleteVolume(fromconn, fromtid); /* zap original volume */ - EGOTO1(mfail, code, "Failed to delete the old volume %u on source\n", - afromvol); - VDONE; - - VPRINT1("Ending transaction on old volume %u on the source ...", - afromvol); - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Failed to end the transaction on the old volume %u on the source\n", - afromvol); - VDONE; - - /* Delete the backup volume on the original site */ - VPRINT1("Creating transaction for backup volume %u on source ...", - backupId); - code = - AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline, &fromtid); - VDONE; - if (!code) { - VPRINT1("Setting flags on backup volume %u on source ...", backupId); - code = - AFSVolSetFlags(fromconn, fromtid, - VTDeleteOnSalvage | VTOutOfService); - EGOTO1(mfail, code, - "Failed to set the flags on the backup volume %u on the source\n", - backupId); - VDONE; - - VPRINT1("Deleting the backup volume %u on the source ...", backupId); - code = AFSVolDeleteVolume(fromconn, fromtid); - EGOTO1(mfail, code, - "Failed to delete the backup volume %u on the source\n", - backupId); - VDONE; - - VPRINT1("Ending transaction on backup volume %u on source ...", - backupId); - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Failed to end the transaction on the backup volume %u on the source\n", - backupId); - VDONE; - } else - code = 0; /* no backup volume? that's okay */ - - fromtid = 0; - if (!(flags & RV_NOCLONE)) { - VPRINT1("Starting transaction on the cloned volume %u ...", newVol); - code = - AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline, - &clonetid); - EGOTO1(mfail, code, - "Failed to start a transaction on the cloned volume%u\n", - newVol); - VDONE; - - /* now delete the clone */ - VPRINT1("Deleting the cloned volume %u ...", newVol); - code = AFSVolDeleteVolume(fromconn, clonetid); - EGOTO1(mfail, code, "Failed to delete the cloned volume %u\n", - newVol); - VDONE; - - VPRINT1("Ending transaction on cloned volume %u ...", newVol); - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - if (!code) - code = rcode; - clonetid = 0; - EGOTO1(mfail, code, - "Failed to end the transaction on the cloned volume %u\n", - newVol); - VDONE; - } - - /* fall through */ - /* END OF MOVE */ - - if (TESTC) { - fprintf(STDOUT, "Fourth test point - operation complete.\n"); - fprintf(STDOUT, "...test here (y, n)? "); - fflush(STDOUT); - fscanf(stdin, "%c", &in); - fscanf(stdin, "%c", &lf); /* toss away */ - if (in == 'y') { - fprintf(STDOUT, "type control-c\n"); - while (1) { - fprintf(stdout, "."); - fflush(stdout); - sleep(1); - } - } - /* or drop through */ - } - - /* normal cleanup code */ - - if (entry.flags & RO_EXISTS) - fprintf(STDERR, "WARNING : readOnly copies still exist \n"); - - if (islocked) { - VPRINT1("Cleanup: Releasing VLDB lock on volume %u ...", afromvol); - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1, - (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP)); - if (vcode) { - VPRINT("\n"); - fprintf(STDERR, - " Could not release the lock on the VLDB entry for the volume %lu \n", - (unsigned long)afromvol); - if (!error) - error = vcode; - } - VDONE; - } - - if (fromtid) { - VPRINT1("Cleanup: Ending transaction on source volume %u ...", - afromvol); - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - if (code || rcode) { - VPRINT("\n"); - fprintf(STDERR, - "Could not end transaction on the source volume %lu\n", - (unsigned long)afromvol); - if (!error) - error = (code ? code : rcode); - } - VDONE; - } - - if (clonetid) { - VPRINT1("Cleanup: Ending transaction on clone volume %u ...", newVol); - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - if (code || rcode) { - VPRINT("\n"); - fprintf(STDERR, - "Could not end transaction on the source's clone volume %lu\n", - (unsigned long)newVol); - if (!error) - error = (code ? code : rcode); - } - VDONE; - } - - if (totid) { - VPRINT1("Cleanup: Ending transaction on destination volume %u ...", - afromvol); - code = AFSVolEndTrans(toconn, totid, &rcode); - if (code) { - VPRINT("\n"); - fprintf(STDERR, - "Could not end transaction on destination volume %lu\n", - (unsigned long)afromvol); - if (!error) - error = (code ? code : rcode); - } - VDONE; - } - if (volName) - free(volName); -#ifdef ENABLE_BUGFIX_1165 - if (infop) - free(infop); -#endif - if (fromconn) - rx_DestroyConnection(fromconn); - if (toconn) - rx_DestroyConnection(toconn); - PrintError("", error); - return error; - - /* come here only when the sky falls */ - mfail: - - if (pntg) { - fprintf(STDOUT, - "vos move: operation interrupted, cleanup in progress...\n"); - fprintf(STDOUT, "clear transaction contexts\n"); - fflush(STDOUT); - } - - /* unlock VLDB entry */ - if (islocked) { - VPRINT1("Recovery: Releasing VLDB lock on volume %u ...", afromvol); - ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1, - (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP)); - VDONE; - } - - if (clonetid) { - VPRINT("Recovery: Ending transaction on clone volume ..."); - AFSVolEndTrans(fromconn, clonetid, &rcode); - VDONE; - } - if (totid) { - VPRINT("Recovery: Ending transaction on destination volume ..."); - AFSVolEndTrans(toconn, totid, &rcode); - VDONE; - } - if (fromtid) { /* put it on-line */ - VPRINT("Recovery: Setting volume flags on source volume ..."); - AFSVolSetFlags(fromconn, fromtid, 0); - VDONE; - - VPRINT("Recovery: Ending transaction on source volume ..."); - AFSVolEndTrans(fromconn, fromtid, &rcode); - VDONE; - } - - VPRINT("Recovery: Accessing VLDB.\n"); - vcode = VLDB_GetEntryByID(afromvol, -1, &entry); - if (vcode) { - fprintf(STDOUT, "FATAL: VLDB access error: abort cleanup\n"); - fflush(STDOUT); - goto done; - } - MapHostToNetwork(&entry); - - /* Delete either the volume on the source location or the target location. - * If the vldb entry still points to the source location, then we know the - * volume move didn't finish so we remove the volume from the target - * location. Otherwise, we remove the volume from the source location. - */ - if (Lp_Match(afromserver, afrompart, &entry)) { /* didn't move - delete target volume */ - if (pntg) { - fprintf(STDOUT, - "move incomplete - attempt cleanup of target partition - no guarantee\n"); - fflush(STDOUT); - } - - if (volid && toconn) { - VPRINT1 - ("Recovery: Creating transaction for destination volume %u ...", - volid); - code = - AFSVolTransCreate(toconn, volid, atopart, ITOffline, &totid); - - if (!code) { - VDONE; - - VPRINT1 - ("Recovery: Setting flags on destination volume %u ...", - volid); - AFSVolSetFlags(toconn, totid, - VTDeleteOnSalvage | VTOutOfService); - VDONE; - - VPRINT1("Recovery: Deleting destination volume %u ...", - volid); - AFSVolDeleteVolume(toconn, totid); - VDONE; - - VPRINT1 - ("Recovery: Ending transaction on destination volume %u ...", - volid); - AFSVolEndTrans(toconn, totid, &rcode); - VDONE; - } else { - VPRINT1 - ("\nRecovery: Unable to start transaction on destination volume %u.\n", - afromvol); - } - } - - /* put source volume on-line */ - if (fromconn) { - VPRINT1("Recovery: Creating transaction on source volume %u ...", - afromvol); - code = - AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, - &fromtid); - if (!code) { - VDONE; - - VPRINT1("Recovery: Setting flags on source volume %u ...", - afromvol); - AFSVolSetFlags(fromconn, fromtid, 0); - VDONE; - - VPRINT1 - ("Recovery: Ending transaction on source volume %u ...", - afromvol); - AFSVolEndTrans(fromconn, fromtid, &rcode); - VDONE; - } else { - VPRINT1 - ("\nRecovery: Unable to start transaction on source volume %u.\n", - afromvol); - } - } - } else { /* yep, move complete */ - if (pntg) { - fprintf(STDOUT, - "move complete - attempt cleanup of source partition - no guarantee\n"); - fflush(STDOUT); - } - - /* delete backup volume */ - if (fromconn) { - VPRINT1("Recovery: Creating transaction on backup volume %u ...", - backupId); - code = - AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline, - &fromtid); - if (!code) { - VDONE; - - VPRINT1("Recovery: Setting flags on backup volume %u ...", - backupId); - AFSVolSetFlags(fromconn, fromtid, - VTDeleteOnSalvage | VTOutOfService); - VDONE; - - VPRINT1("Recovery: Deleting backup volume %u ...", backupId); - AFSVolDeleteVolume(fromconn, fromtid); - VDONE; - - VPRINT1 - ("Recovery: Ending transaction on backup volume %u ...", - backupId); - AFSVolEndTrans(fromconn, fromtid, &rcode); - VDONE; - } else { - VPRINT1 - ("\nRecovery: Unable to start transaction on backup volume %u.\n", - backupId); - } - - /* delete source volume */ - VPRINT1("Recovery: Creating transaction on source volume %u ...", - afromvol); - code = - AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, - &fromtid); - if (!code) { - VDONE; - - VPRINT1("Recovery: Setting flags on backup volume %u ...", - afromvol); - AFSVolSetFlags(fromconn, fromtid, - VTDeleteOnSalvage | VTOutOfService); - VDONE; - - if (atoserver != afromserver) { - VPRINT("Recovery: Setting volume forwarding pointer ..."); - AFSVolSetForwarding(fromconn, fromtid, atoserver); - VDONE; - } - - VPRINT1("Recovery: Deleting source volume %u ...", afromvol); - AFSVolDeleteVolume(fromconn, fromtid); - VDONE; - - VPRINT1 - ("Recovery: Ending transaction on source volume %u ...", - afromvol); - AFSVolEndTrans(fromconn, fromtid, &rcode); - VDONE; - } else { - VPRINT1 - ("\nRecovery: Unable to start transaction on source volume %u.\n", - afromvol); - } - } - } - - /* common cleanup - delete local clone */ - if (newVol) { - VPRINT1("Recovery: Creating transaction on clone volume %u ...", - newVol); - code = - AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline, - &clonetid); - if (!code) { - VDONE; - - VPRINT1("Recovery: Deleting clone volume %u ...", newVol); - AFSVolDeleteVolume(fromconn, clonetid); - VDONE; - - VPRINT1("Recovery: Ending transaction on clone volume %u ...", - newVol); - AFSVolEndTrans(fromconn, clonetid, &rcode); - VDONE; - } else { - VPRINT1 - ("\nRecovery: Unable to start transaction on source volume %u.\n", - afromvol); - } - } - - /* unlock VLDB entry */ - VPRINT1("Recovery: Releasing lock on VLDB entry for volume %u ...", - afromvol); - ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1, - (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP)); - VDONE; - - done: /* routine cleanup */ - if (volName) - free(volName); -#ifdef ENABLE_BUGFIX_1165 - if (infop) - free(infop); -#endif - if (fromconn) - rx_DestroyConnection(fromconn); - if (toconn) - rx_DestroyConnection(toconn); - - if (pntg) { - fprintf(STDOUT, "cleanup complete - user verify desired result\n"); - fflush(STDOUT); - } - exit(1); -} - - -int -UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart, - afs_int32 atoserver, afs_int32 atopart) -{ - return UV_MoveVolume2(afromvol, afromserver, afrompart, - atoserver, atopart, 0); -} - - -/* Copy volume from to - * . The new volume is named by . The new volume - * has ID if that is nonzero; otherwise a new ID is allocated - * from the VLDB. the following flags are supported: - * - * RV_RDONLY - target volume is RO - * RV_OFFLINE - leave target volume offline - * RV_CPINCR - do incremental dump if target exists - * RV_NOVLDB - don't create/update VLDB entry - * RV_NOCLONE - don't use a copy clone - */ -int -UV_CopyVolume2(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart, - char *atovolname, afs_int32 atoserver, afs_int32 atopart, - afs_int32 atovolid, int flags) -{ - struct rx_connection *toconn, *fromconn; - afs_int32 fromtid, totid, clonetid; - char vname[64]; - afs_int32 rcode; - afs_int32 fromDate, cloneFromDate; - struct restoreCookie cookie; - register afs_int32 vcode, code; - afs_int32 cloneVol, newVol, volflag; - struct volser_status tstatus; - struct destServer destination; - - struct nvldbentry entry, newentry, storeEntry; - int islocked, pntg; - afs_int32 error; - int justclone = 0; - - islocked = 0; - fromconn = (struct rx_connection *)0; - toconn = (struct rx_connection *)0; - fromtid = 0; - totid = 0; - clonetid = 0; - error = 0; - pntg = 0; - newVol = 0; - - /* support control-c processing */ - if (setjmp(env)) - goto mfail; - (void)signal(SIGINT, sigint_handler); - - vcode = VLDB_GetEntryByID(afromvol, -1, &entry); - EGOTO1(mfail, vcode, - "Could not fetch the entry for the volume %u from the VLDB \n", - afromvol); - MapHostToNetwork(&entry); - - pntg = 1; - toconn = UV_Bind(atoserver, AFSCONF_VOLUMEPORT); /* get connections to the servers */ - fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT); - fromtid = totid = 0; /* initialize to uncreated */ - - - /* check if we can shortcut and use a local clone instead of a full copy */ - if (afromserver == atoserver && afrompart == atopart) { - justclone = 1; - } - - /* *** - * clone the read/write volume locally. - * ***/ - - cloneVol = 0; - if (!(flags & RV_NOCLONE)) { - VPRINT1("Starting transaction on source volume %u ...", afromvol); - code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, - &fromtid); - EGOTO1(mfail, code, "Failed to create transaction on the volume %u\n", - afromvol); - VDONE; - - /* Get a clone id */ - VPRINT1("Allocating new volume id for clone of volume %u ...", - afromvol); - cloneVol = 0; - vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &cloneVol); - EGOTO1(mfail, vcode, - "Could not get an ID for the clone of volume %u from the VLDB\n", - afromvol); - VDONE; - } - - if (atovolid) { - newVol = atovolid; - } else { - /* Get a new volume id */ - VPRINT1("Allocating new volume id for copy of volume %u ...", afromvol); - newVol = 0; - vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &newVol); - EGOTO1(mfail, vcode, - "Could not get an ID for the copy of volume %u from the VLDB\n", - afromvol); - VDONE; - } - - if (!(flags & RV_NOCLONE)) { - /* Do the clone. Default flags on clone are set to delete on salvage and out of service */ - VPRINT1("Cloning source volume %u ...", afromvol); - strcpy(vname, "copy-clone-temp"); - code = - AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, - &cloneVol); - EGOTO1(mfail, code, "Failed to clone the source volume %u\n", - afromvol); - VDONE; - - VPRINT1("Ending the transaction on the source volume %u ...", afromvol); - rcode = 0; - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Failed to end the transaction on the source volume %u\n", - afromvol); - VDONE; - } - - /* *** - * Create the destination volume - * ***/ - - if (!(flags & RV_NOCLONE)) { - VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol); - code = - AFSVolTransCreate(fromconn, cloneVol, afrompart, ITOffline, - &clonetid); - EGOTO1(mfail, code, - "Failed to start a transaction on the cloned volume%u\n", - cloneVol); - VDONE; - - VPRINT1("Setting flags on cloned volume %u ...", cloneVol); - code = - AFSVolSetFlags(fromconn, clonetid, - VTDeleteOnSalvage | VTOutOfService); /*redundant */ - EGOTO1(mfail, code, "Could not set flags on the cloned volume %u\n", - cloneVol); - VDONE; - - /* remember time from which we've dumped the volume */ - VPRINT1("Getting status of cloned volume %u ...", cloneVol); - code = AFSVolGetStatus(fromconn, clonetid, &tstatus); - EGOTO1(mfail, code, - "Failed to get the status of the cloned volume %u\n", - cloneVol); - VDONE; - - fromDate = tstatus.creationDate - CLOCKSKEW; - } else { - fromDate = 0; - } - - /* create a volume on the target machine */ - cloneFromDate = 0; - code = AFSVolTransCreate(toconn, newVol, atopart, ITOffline, &totid); - if (!code) { - if ((flags & RV_CPINCR)) { - VPRINT1("Getting status of pre-existing volume %u ...", newVol); - code = AFSVolGetStatus(toconn, totid, &tstatus); - EGOTO1(mfail, code, - "Failed to get the status of the pre-existing volume %u\n", - newVol); - VDONE; - - /* Using the update date should be OK here, but add some fudge */ - cloneFromDate = tstatus.updateDate - CLOCKSKEW; - if ((flags & RV_NOCLONE)) - fromDate = cloneFromDate; - - /* XXX We should check that the source volume's creationDate is - * XXX not newer than the existing target volume, and if not, - * XXX throw away the existing target and do a full dump. */ - - goto cpincr; - } - - /* Delete the existing volume. - * While we are deleting the volume in these steps, the transaction - * we started against the cloned volume (clonetid above) will be - * sitting idle. It will get cleaned up after 600 seconds - */ - VPRINT1("Deleting pre-existing volume %u on destination ...", newVol); - code = AFSVolDeleteVolume(toconn, totid); - EGOTO1(mfail, code, - "Could not delete the pre-existing volume %u on destination\n", - newVol); - VDONE; - - VPRINT1 - ("Ending transaction on pre-existing volume %u on destination ...", - newVol); - code = AFSVolEndTrans(toconn, totid, &rcode); - totid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Could not end the transaction on pre-existing volume %u on destination\n", - newVol); - VDONE; - } - - VPRINT1("Creating the destination volume %u ...", newVol); - code = - AFSVolCreateVolume(toconn, atopart, atovolname, - (flags & RV_RDONLY) ? volser_RO : volser_RW, - newVol, &newVol, &totid); - EGOTO1(mfail, code, "Failed to create the destination volume %u\n", - newVol); - VDONE; - - VPRINT1("Setting volume flags on destination volume %u ...", newVol); - code = - AFSVolSetFlags(toconn, totid, (VTDeleteOnSalvage | VTOutOfService)); - EGOTO1(mfail, code, - "Failed to set the flags on the destination volume %u\n", newVol); - VDONE; - -cpincr: - - destination.destHost = ntohl(atoserver); - destination.destPort = AFSCONF_VOLUMEPORT; - destination.destSSID = 1; - - strncpy(cookie.name, atovolname, VOLSER_OLDMAXVOLNAME); - cookie.type = (flags & RV_RDONLY) ? ROVOL : RWVOL; - cookie.parent = 0; - cookie.clone = 0; - - /*** - * Now dump the clone to the new volume - ***/ - - if (!(flags & RV_NOCLONE)) { - /* XXX probably should have some code here that checks to see if - * XXX we are copying to same server and partition - if so, just - * XXX use a clone to save disk space */ - - /* Copy the clone to the new volume */ - VPRINT2("Dumping from clone %u on source to volume %u on destination ...", - cloneVol, newVol); - code = - AFSVolForward(fromconn, clonetid, cloneFromDate, &destination, - totid, &cookie); - EGOTO1(mfail, code, "Failed to move data for the volume %u\n", - newVol); - VDONE; - - VPRINT1("Ending transaction on cloned volume %u ...", cloneVol); - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - if (!code) - code = rcode; - clonetid = 0; - EGOTO1(mfail, code, - "Failed to end the transaction on the cloned volume %u\n", - cloneVol); - VDONE; - } - - /* *** - * reattach to the main-line volume, and incrementally dump it. - * ***/ - - VPRINT1("Starting transaction on source volume %u ...", afromvol); - code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid); - EGOTO1(mfail, code, - "Failed to create a transaction on the source volume %u\n", - afromvol); - VDONE; - - /* now do the incremental */ - VPRINT2 - ("Doing the%s dump from source to destination for volume %u ... ", - (flags & RV_NOCLONE) ? "" : " incremental", - afromvol); - code = - AFSVolForward(fromconn, fromtid, fromDate, &destination, totid, - &cookie); - EGOTO1(mfail, code, - "Failed to do the%s dump from old site to new site\n", - afromvol); - VDONE; - - VPRINT1("Setting volume flags on destination volume %u ...", newVol); - volflag = ((flags & RV_OFFLINE) ? VTOutOfService : 0); /* off or on-line */ - code = AFSVolSetFlags(toconn, totid, volflag); - EGOTO(mfail, code, - "Failed to set the flags to make destination volume online\n"); - VDONE; - - /* put new volume online */ - VPRINT1("Ending transaction on destination volume %u ...", newVol); - code = AFSVolEndTrans(toconn, totid, &rcode); - totid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Failed to end the transaction on the destination volume %u\n", - newVol); - VDONE; - - VPRINT1("Ending transaction on source volume %u ...", afromvol); - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (!code) - code = rcode; - EGOTO1(mfail, code, - "Failed to end the transaction on the source volume %u\n", - afromvol); - VDONE; - - fromtid = 0; - - if (!(flags & RV_NOCLONE)) { - VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol); - code = - AFSVolTransCreate(fromconn, cloneVol, afrompart, ITOffline, - &clonetid); - EGOTO1(mfail, code, - "Failed to start a transaction on the cloned volume%u\n", - cloneVol); - VDONE; - - /* now delete the clone */ - VPRINT1("Deleting the cloned volume %u ...", cloneVol); - code = AFSVolDeleteVolume(fromconn, clonetid); - EGOTO1(mfail, code, "Failed to delete the cloned volume %u\n", - cloneVol); - VDONE; - - VPRINT1("Ending transaction on cloned volume %u ...", cloneVol); - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - if (!code) - code = rcode; - clonetid = 0; - EGOTO1(mfail, code, - "Failed to end the transaction on the cloned volume %u\n", - cloneVol); - VDONE; - } - - if (!(flags & RV_NOVLDB)) { - /* create the vldb entry for the copied volume */ - strncpy(newentry.name, atovolname, VOLSER_OLDMAXVOLNAME); - newentry.nServers = 1; - newentry.serverNumber[0] = atoserver; - newentry.serverPartition[0] = atopart; - newentry.flags = (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS; - newentry.serverFlags[0] = (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL; - newentry.volumeId[RWVOL] = newVol; - newentry.volumeId[ROVOL] = (flags & RV_RDONLY) ? newVol : 0; - newentry.volumeId[BACKVOL] = 0; - newentry.cloneId = 0; - /*map into right byte order, before passing to xdr, the stuff has to be in host - * byte order. Xdr converts it into network order */ - MapNetworkToHost(&newentry, &storeEntry); - /* create the vldb entry */ - vcode = VLDB_CreateEntry(&storeEntry); - if (vcode) { - fprintf(STDERR, - "Could not create a VLDB entry for the volume %s %lu\n", - atovolname, (unsigned long)newVol); - /*destroy the created volume */ - VPRINT1("Deleting the newly created volume %u\n", newVol); - AFSVolDeleteVolume(toconn, totid); - error = vcode; - goto mfail; - } - VPRINT2("Created the VLDB entry for the volume %s %u\n", atovolname, - newVol); - } - - /* normal cleanup code */ - - if (fromtid) { - VPRINT1("Cleanup: Ending transaction on source volume %u ...", - afromvol); - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - if (code || rcode) { - VPRINT("\n"); - fprintf(STDERR, - "Could not end transaction on the source volume %lu\n", - (unsigned long)afromvol); - if (!error) - error = (code ? code : rcode); - } - VDONE; - } - - if (clonetid) { - VPRINT1("Cleanup: Ending transaction on clone volume %u ...", - cloneVol); - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - if (code || rcode) { - VPRINT("\n"); - fprintf(STDERR, - "Could not end transaction on the source's clone volume %lu\n", - (unsigned long)cloneVol); - if (!error) - error = (code ? code : rcode); - } - VDONE; - } - - if (totid) { - VPRINT1("Cleanup: Ending transaction on destination volume %u ...", - newVol); - code = AFSVolEndTrans(toconn, totid, &rcode); - if (code) { - VPRINT("\n"); - fprintf(STDERR, - "Could not end transaction on destination volume %lu\n", - (unsigned long)newVol); - if (!error) - error = (code ? code : rcode); - } - VDONE; - } - if (fromconn) - rx_DestroyConnection(fromconn); - if (toconn) - rx_DestroyConnection(toconn); - PrintError("", error); - return error; - - /* come here only when the sky falls */ - mfail: - - if (pntg) { - fprintf(STDOUT, - "vos copy: operation interrupted, cleanup in progress...\n"); - fprintf(STDOUT, "clear transaction contexts\n"); - fflush(STDOUT); - } - - if (clonetid) { - VPRINT("Recovery: Ending transaction on clone volume ..."); - AFSVolEndTrans(fromconn, clonetid, &rcode); - VDONE; - } - if (totid) { - VPRINT("Recovery: Ending transaction on destination volume ..."); - AFSVolEndTrans(toconn, totid, &rcode); - VDONE; - } - if (fromtid) { /* put it on-line */ - VPRINT("Recovery: Ending transaction on source volume ..."); - AFSVolEndTrans(fromconn, fromtid, &rcode); - VDONE; - } - - VPRINT("Recovery: Accessing VLDB.\n"); - vcode = VLDB_GetEntryByID(afromvol, -1, &entry); - if (vcode) { - fprintf(STDOUT, "FATAL: VLDB access error: abort cleanup\n"); - fflush(STDOUT); - goto done; - } - MapHostToNetwork(&entry); - - /* common cleanup - delete local clone */ - if (cloneVol) { - VPRINT1("Recovery: Creating transaction on clone volume %u ...", - cloneVol); - code = - AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline, - &clonetid); - if (!code) { - VDONE; - - VPRINT1("Recovery: Deleting clone volume %u ...", cloneVol); - AFSVolDeleteVolume(fromconn, clonetid); - VDONE; - - VPRINT1("Recovery: Ending transaction on clone volume %u ...", - cloneVol); - AFSVolEndTrans(fromconn, clonetid, &rcode); - VDONE; - } else { - VPRINT1 - ("\nRecovery: Unable to start transaction on clone volume %u.\n", - cloneVol); - } - } - - done: /* routine cleanup */ - if (fromconn) - rx_DestroyConnection(fromconn); - if (toconn) - rx_DestroyConnection(toconn); - - if (pntg) { - fprintf(STDOUT, "cleanup complete - user verify desired result\n"); - fflush(STDOUT); - } - exit(1); -} - - -int -UV_CopyVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart, - char *atovolname, afs_int32 atoserver, afs_int32 atopart) -{ - return UV_CopyVolume2(afromvol, afromserver, afrompart, - atovolname, atoserver, atopart, 0, 0); -} - - - -/* Make a new backup of volume on and - * if one already exists, update it - */ - -int -UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid) -{ - struct rx_connection *aconn = (struct rx_connection *)0; - afs_int32 ttid = 0, btid = 0; - afs_int32 backupID; - afs_int32 code = 0, rcode = 0; - char vname[VOLSER_MAXVOLNAME + 1]; - struct nvldbentry entry, storeEntry; - afs_int32 error = 0; - int vldblocked = 0, vldbmod = 0, backexists = 1; - - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - - /* the calls to VLDB will succeed only if avolid is a RW volume, - * since we are following the RW hash chain for searching */ - code = VLDB_GetEntryByID(avolid, RWVOL, &entry); - if (code) { - fprintf(STDERR, - "Could not fetch the entry for the volume %lu from the VLDB \n", - (unsigned long)avolid); - error = code; - goto bfail; - } - MapHostToNetwork(&entry); - - /* These operations require the VLDB be locked since it means the VLDB - * will change or the vldb is already locked. - */ - if (!(entry.flags & BACK_EXISTS) || /* backup volume doesnt exist */ - (entry.flags & VLOP_ALLOPERS) || /* vldb lock already held */ - (entry.volumeId[BACKVOL] == INVALID_BID)) { /* no assigned backup volume id */ - - code = ubik_Call(VL_SetLock, cstruct, 0, avolid, RWVOL, VLOP_BACKUP); - if (code) { - fprintf(STDERR, - "Could not lock the VLDB entry for the volume %lu\n", - (unsigned long)avolid); - error = code; - goto bfail; - } - vldblocked = 1; - - /* Reread the vldb entry */ - code = VLDB_GetEntryByID(avolid, RWVOL, &entry); - if (code) { - fprintf(STDERR, - "Could not fetch the entry for the volume %lu from the VLDB \n", - (unsigned long)avolid); - error = code; - goto bfail; - } - MapHostToNetwork(&entry); - } - - if (!ISNAMEVALID(entry.name)) { - fprintf(STDERR, "Name of the volume %s exceeds the size limit\n", - entry.name); - error = VOLSERBADNAME; - goto bfail; - } - - backupID = entry.volumeId[BACKVOL]; - if (backupID == INVALID_BID) { - /* Get a backup volume id from the VLDB and update the vldb - * entry with it. - */ - code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &backupID); - if (code) { - fprintf(STDERR, - "Could not allocate ID for the backup volume of %lu from the VLDB\n", - (unsigned long)avolid); - error = code; - goto bfail; - } - entry.volumeId[BACKVOL] = backupID; - vldbmod = 1; - } - - /* Test to see if the backup volume exists by trying to create - * a transaction on the backup volume. We've assumed the backup exists. - */ - code = AFSVolTransCreate(aconn, backupID, apart, ITOffline, &btid); - if (code) { - if (code != VNOVOL) { - fprintf(STDERR, "Could not reach the backup volume %lu\n", - (unsigned long)backupID); - error = code; - goto bfail; - } - backexists = 0; /* backup volume does not exist */ - } - if (btid) { - code = AFSVolEndTrans(aconn, btid, &rcode); - btid = 0; - if (code || rcode) { - fprintf(STDERR, - "Could not end transaction on the previous backup volume %lu\n", - (unsigned long)backupID); - error = (code ? code : rcode); - goto bfail; - } - } - - /* Now go ahead and try to clone the RW volume. - * First start a transaction on the RW volume - */ - code = AFSVolTransCreate(aconn, avolid, apart, ITBusy, &ttid); - if (code) { - fprintf(STDERR, "Could not start a transaction on the volume %lu\n", - (unsigned long)avolid); - error = code; - goto bfail; - } - - /* Clone or reclone the volume, depending on whether the backup - * volume exists or not - */ - if (backexists) { - VPRINT1("Re-cloning backup volume %u ...", backupID); - - code = AFSVolReClone(aconn, ttid, backupID); - if (code) { - fprintf(STDERR, "Could not re-clone backup volume %lu\n", - (unsigned long)backupID); - error = code; - goto bfail; - } - } else { - VPRINT1("Creating a new backup clone %u ...", backupID); - - strcpy(vname, entry.name); - strcat(vname, ".backup"); - - code = AFSVolClone(aconn, ttid, 0, backupVolume, vname, &backupID); - if (code) { - fprintf(STDERR, "Failed to clone the volume %lu\n", - (unsigned long)avolid); - error = code; - goto bfail; - } - } - - /* End the transaction on the RW volume */ - code = AFSVolEndTrans(aconn, ttid, &rcode); - ttid = 0; - if (code || rcode) { - fprintf(STDERR, - "Failed to end the transaction on the rw volume %lu\n", - (unsigned long)avolid); - error = (code ? code : rcode); - goto bfail; - } - - /* Mork vldb as backup exists */ - if (!(entry.flags & BACK_EXISTS)) { - entry.flags |= BACK_EXISTS; - vldbmod = 1; - } - - /* Now go back to the backup volume and bring it on line */ - code = AFSVolTransCreate(aconn, backupID, apart, ITOffline, &btid); - if (code) { - fprintf(STDERR, - "Failed to start a transaction on the backup volume %lu\n", - (unsigned long)backupID); - error = code; - goto bfail; - } - - code = AFSVolSetFlags(aconn, btid, 0); - if (code) { - fprintf(STDERR, "Could not mark the backup volume %lu on line \n", - (unsigned long)backupID); - error = code; - goto bfail; - } - - code = AFSVolEndTrans(aconn, btid, &rcode); - btid = 0; - if (code || rcode) { - fprintf(STDERR, - "Failed to end the transaction on the backup volume %lu\n", - (unsigned long)backupID); - error = (code ? code : rcode); - goto bfail; - } - - VDONE; - - /* Will update the vldb below */ - - bfail: - if (ttid) { - code = AFSVolEndTrans(aconn, ttid, &rcode); - if (code || rcode) { - fprintf(STDERR, "Could not end transaction on the volume %lu\n", - (unsigned long)avolid); - if (!error) - error = (code ? code : rcode); - } - } - - if (btid) { - code = AFSVolEndTrans(aconn, btid, &rcode); - if (code || rcode) { - fprintf(STDERR, - "Could not end transaction the backup volume %lu\n", - (unsigned long)backupID); - if (!error) - error = (code ? code : rcode); - } - } - - /* Now update the vldb - if modified */ - if (vldblocked) { - if (vldbmod) { - MapNetworkToHost(&entry, &storeEntry); - code = - VLDB_ReplaceEntry(avolid, RWVOL, &storeEntry, - (LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP)); - if (code) { - fprintf(STDERR, - "Could not update the VLDB entry for the volume %lu \n", - (unsigned long)avolid); - if (!error) - error = code; - } - } else { - code = - ubik_Call(VL_ReleaseLock, cstruct, 0, avolid, RWVOL, - (LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP)); - if (code) { - fprintf(STDERR, - "Could not unlock the VLDB entry for the volume %lu \n", - (unsigned long)avolid); - if (!error) - error = code; - } - } - } - - if (aconn) - rx_DestroyConnection(aconn); - - PrintError("", error); - return error; -} - -/* Make a new clone of volume on and - * using volume ID , or a new ID allocated from the VLDB. - * The new volume is named by , or by appending ".clone" to - * the existing name if is NULL. The following flags are - * supported: - * - * RV_RDONLY - target volume is RO - * RV_OFFLINE - leave target volume offline - */ - -int -UV_CloneVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid, - afs_int32 acloneid, char *aname, int flags) -{ - struct rx_connection *aconn = (struct rx_connection *)0; - afs_int32 ttid = 0, btid = 0; - afs_int32 code = 0, rcode = 0; - char vname[VOLSER_MAXVOLNAME + 1]; - afs_int32 error = 0; - int backexists = 1; - volEntries volumeInfo; - - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - - if (!aname) { - volumeInfo.volEntries_val = (volintInfo *) 0; - volumeInfo.volEntries_len = 0; - code = AFSVolListOneVolume(aconn, apart, avolid, &volumeInfo); - if (code) { - fprintf(stderr, "Could not get info for volume %lu\n", - (unsigned long)avolid); - error = code; - goto bfail; - } - strncpy(vname, volumeInfo.volEntries_val[0].name, - VOLSER_OLDMAXVOLNAME - 7); - vname[VOLSER_OLDMAXVOLNAME - 7] = 0; - strcat(vname, ".clone"); - aname = vname; - if (volumeInfo.volEntries_val) - free(volumeInfo.volEntries_val); - } - - if (!acloneid) { - /* Get a clone id */ - VPRINT1("Allocating new volume id for clone of volume %u ...", - avolid); - code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &acloneid); - EGOTO1(bfail, code, - "Could not get an ID for the clone of volume %u from the VLDB\n", - avolid); - VDONE; - } - - /* Test to see if the clone volume exists by trying to create - * a transaction on the clone volume. We've assumed the clone exists. - */ - /* XXX I wonder what happens if the clone has some other parent... */ - code = AFSVolTransCreate(aconn, acloneid, apart, ITOffline, &btid); - if (code) { - if (code != VNOVOL) { - fprintf(STDERR, "Could not reach the clone volume %lu\n", - (unsigned long)acloneid); - error = code; - goto bfail; - } - backexists = 0; /* backup volume does not exist */ - } - if (btid) { - code = AFSVolEndTrans(aconn, btid, &rcode); - btid = 0; - if (code || rcode) { - fprintf(STDERR, - "Could not end transaction on the previous clone volume %lu\n", - (unsigned long)acloneid); - error = (code ? code : rcode); - goto bfail; - } - } - - /* Now go ahead and try to clone the RW volume. - * First start a transaction on the RW volume - */ - code = AFSVolTransCreate(aconn, avolid, apart, ITBusy, &ttid); - if (code) { - fprintf(STDERR, "Could not start a transaction on the volume %lu\n", - (unsigned long)avolid); - error = code; - goto bfail; - } - - /* Clone or reclone the volume, depending on whether the backup - * volume exists or not - */ - if (backexists) { - VPRINT1("Re-cloning clone volume %u ...", acloneid); - - code = AFSVolReClone(aconn, ttid, acloneid); - if (code) { - fprintf(STDERR, "Could not re-clone backup volume %lu\n", - (unsigned long)acloneid); - error = code; - goto bfail; - } - } else { - VPRINT1("Creating a new clone %u ...", acloneid); - - code = AFSVolClone(aconn, ttid, 0, - (flags & RV_RDONLY) ? readonlyVolume : backupVolume, - aname, &acloneid); - if (code) { - fprintf(STDERR, "Failed to clone the volume %lu\n", - (unsigned long)avolid); - error = code; - goto bfail; - } - } - - /* End the transaction on the RW volume */ - code = AFSVolEndTrans(aconn, ttid, &rcode); - ttid = 0; - if (code || rcode) { - fprintf(STDERR, - "Failed to end the transaction on the rw volume %lu\n", - (unsigned long)avolid); - error = (code ? code : rcode); - goto bfail; - } - - /* Now go back to the backup volume and bring it on line */ - if (!(flags & RV_OFFLINE)) { - code = AFSVolTransCreate(aconn, acloneid, apart, ITOffline, &btid); - if (code) { - fprintf(STDERR, - "Failed to start a transaction on the clone volume %lu\n", - (unsigned long)acloneid); - error = code; - goto bfail; - } - - code = AFSVolSetFlags(aconn, btid, 0); - if (code) { - fprintf(STDERR, "Could not mark the clone volume %lu on line \n", - (unsigned long)acloneid); - error = code; - goto bfail; - } - - code = AFSVolEndTrans(aconn, btid, &rcode); - btid = 0; - if (code || rcode) { - fprintf(STDERR, - "Failed to end the transaction on the clone volume %lu\n", - (unsigned long)acloneid); - error = (code ? code : rcode); - goto bfail; - } - } - - VDONE; - - bfail: - if (ttid) { - code = AFSVolEndTrans(aconn, ttid, &rcode); - if (code || rcode) { - fprintf(STDERR, "Could not end transaction on the volume %lu\n", - (unsigned long)avolid); - if (!error) - error = (code ? code : rcode); - } - } - - if (btid) { - code = AFSVolEndTrans(aconn, btid, &rcode); - if (code || rcode) { - fprintf(STDERR, - "Could not end transaction on the clone volume %lu\n", - (unsigned long)acloneid); - if (!error) - error = (code ? code : rcode); - } - } - - if (aconn) - rx_DestroyConnection(aconn); - - PrintError("", error); - return error; -} - -static int -DelVol(struct rx_connection *conn, afs_int32 vid, afs_int32 part, - afs_int32 flags) -{ - afs_int32 acode, ccode, rcode, tid; - ccode = rcode = tid = 0; - - acode = AFSVolTransCreate(conn, vid, part, flags, &tid); - if (!acode) { /* It really was there */ - acode = AFSVolDeleteVolume(conn, tid); - if (acode) { - fprintf(STDERR, "Failed to delete volume %lu.\n", - (unsigned long)vid); - PrintError("", acode); - } - ccode = AFSVolEndTrans(conn, tid, &rcode); - if (!ccode) - ccode = rcode; - if (ccode) { - fprintf(STDERR, "Failed to end transaction on volume %lu.\n", - (unsigned long)vid); - PrintError("", ccode); - } - } - - return acode; -} - -#define ONERROR(ec, ep, es) if (ec) { fprintf(STDERR, (es), (ep)); error = (ec); goto rfail; } -#define ERROREXIT(ec) { error = (ec); goto rfail; } - -/* Get a "transaction" on this replica. Create the volume - * if necessary. Return the time from which a dump should - * be made (0 if it's a new volume) - */ -static int -GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index, - struct rx_connection **connPtr, afs_int32 * transPtr, - afs_int32 * timePtr) -{ - afs_int32 volid; - struct volser_status tstatus; - int code, rcode, tcode; - - *connPtr = (struct rx_connection *)0; - *timePtr = 0; - *transPtr = 0; - - /* get connection to the replication site */ - *connPtr = UV_Bind(vldbEntryPtr->serverNumber[index], AFSCONF_VOLUMEPORT); - if (!*connPtr) - goto fail; /* server is down */ - - volid = vldbEntryPtr->volumeId[ROVOL]; - if (volid) - code = - AFSVolTransCreate(*connPtr, volid, - vldbEntryPtr->serverPartition[index], ITOffline, - transPtr); - - /* If the volume does not exist, create it */ - if (!volid || code) { - char volname[64]; - - if (volid && (code != VNOVOL)) { - PrintError("Failed to start a transaction on the RO volume.\n", - code); - goto fail; - } - - strcpy(volname, vldbEntryPtr->name); - strcat(volname, ".readonly"); - - if (verbose) { - fprintf(STDOUT, - "Creating new volume %lu on replication site %s: ", - (unsigned long)volid, - hostutil_GetNameByINet(vldbEntryPtr-> - serverNumber[index])); - fflush(STDOUT); - } - - code = - AFSVolCreateVolume(*connPtr, vldbEntryPtr->serverPartition[index], - volname, volser_RO, - vldbEntryPtr->volumeId[RWVOL], &volid, - transPtr); - if (code) { - PrintError("Failed to create the ro volume: ", code); - goto fail; - } - vldbEntryPtr->volumeId[ROVOL] = volid; - - VDONE; - - /* The following is a bit redundant, since create sets these flags by default */ - code = - AFSVolSetFlags(*connPtr, *transPtr, - VTDeleteOnSalvage | VTOutOfService); - if (code) { - PrintError("Failed to set flags on the ro volume: ", code); - goto fail; - } - } - - /* Otherwise, the transaction did succeed, so get the creation date of the - * latest RO volume on the replication site - */ - else { - VPRINT2("Updating existing ro volume %u on %s ...\n", volid, - hostutil_GetNameByINet(vldbEntryPtr->serverNumber[index])); - - code = AFSVolGetStatus(*connPtr, *transPtr, &tstatus); - if (code) { - PrintError("Failed to get status of volume on destination: ", - code); - goto fail; - } - *timePtr = tstatus.creationDate - CLOCKSKEW; - } - - return 0; - - fail: - if (*transPtr) { - tcode = AFSVolEndTrans(*connPtr, *transPtr, &rcode); - *transPtr = 0; - if (!tcode) - tcode = rcode; - if (tcode) - PrintError("Could not end transaction on a ro volume: ", tcode); - } - - return code; -} - -static int -SimulateForwardMultiple(struct rx_connection *fromconn, afs_int32 fromtid, - afs_int32 fromdate, manyDests * tr, afs_int32 flags, - void *cookie, manyResults * results) -{ - int i; - - for (i = 0; i < tr->manyDests_len; i++) { - results->manyResults_val[i] = - AFSVolForward(fromconn, fromtid, fromdate, - &(tr->manyDests_val[i].server), - tr->manyDests_val[i].trans, cookie); - } - return 0; -} - - -static int -rel_compar(struct release *r1, struct release *r2) -{ - return (r1->time - r2->time); -} - -/* UV_ReleaseVolume() - * Release volume on to all - * its RO sites (full release). Unless the previous release was - * incomplete: in which case we bring the remaining incomplete - * volumes up to date with the volumes that were released - * successfully. - * forceflag: Performs a full release. - * - * Will create a clone from the RW, then dump the clone out to - * the remaining replicas. If there is more than 1 RO sites, - * ensure that the VLDB says at least one RO is available all - * the time: Influences when we write back the VLDB entry. - */ - -int -UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver, - afs_int32 afrompart, int forceflag) -{ - char vname[64]; - afs_int32 code, vcode, rcode, tcode; - afs_int32 cloneVolId, roVolId; - struct replica *replicas = 0; - struct nvldbentry entry, storeEntry; - int i, volcount, m, fullrelease, vldbindex; - int failure; - struct restoreCookie cookie; - struct rx_connection **toconns = 0; - struct release *times = 0; - int nservers = 0; - struct rx_connection *fromconn = (struct rx_connection *)0; - afs_int32 error = 0; - int islocked = 0; - afs_int32 clonetid = 0, onlinetid; - afs_int32 fromtid = 0; - afs_uint32 fromdate, thisdate; - int s; - manyDests tr; - manyResults results; - int rwindex, roindex, roclone, roexists; - afs_int32 rwcrdate, clcrdate; - struct rtime { - int validtime; - afs_uint32 time; - } remembertime[NMAXNSERVERS]; - int releasecount = 0; - struct volser_status volstatus; - - memset((char *)remembertime, 0, sizeof(remembertime)); - memset((char *)&results, 0, sizeof(results)); - - vcode = ubik_Call(VL_SetLock, cstruct, 0, afromvol, RWVOL, VLOP_RELEASE); - if (vcode != VL_RERELEASE) - ONERROR(vcode, afromvol, - "Could not lock the VLDB entry for the volume %u.\n"); - islocked = 1; - - /* Get the vldb entry in readable format */ - vcode = VLDB_GetEntryByID(afromvol, RWVOL, &entry); - ONERROR(vcode, afromvol, - "Could not fetch the entry for the volume %u from the VLDB.\n"); - MapHostToNetwork(&entry); - - if (verbose) - EnumerateEntry(&entry); - - if (!ISNAMEVALID(entry.name)) - ONERROR(VOLSERBADOP, entry.name, - "Volume name %s is too long, rename before releasing.\n"); - if (entry.volumeId[RWVOL] != afromvol) - ONERROR(VOLSERBADOP, afromvol, - "The volume %u being released is not a read-write volume.\n"); - if (entry.nServers <= 1) - ONERROR(VOLSERBADOP, afromvol, - "Volume %u has no replicas - release operation is meaningless!\n"); - if (strlen(entry.name) > (VOLSER_OLDMAXVOLNAME - 10)) - ONERROR(VOLSERBADOP, entry.name, - "RO volume name %s exceeds (VOLSER_OLDMAXVOLNAME - 10) character limit\n"); - - /* roclone is true if one of the RO volumes is on the same - * partition as the RW volume. In this case, we make the RO volume - * on the same partition a clone instead of a complete copy. - */ - - roindex = Lp_ROMatch(afromserver, afrompart, &entry) - 1; - roclone = ((roindex == -1) ? 0 : 1); - rwindex = Lp_GetRwIndex(&entry); - if (rwindex < 0) - ONERROR(VOLSERNOVOL, 0, "There is no RW volume \n"); - - /* Make sure we have a RO volume id to work with */ - if (entry.volumeId[ROVOL] == INVALID_BID) { - /* need to get a new RO volume id */ - vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &roVolId); - ONERROR(vcode, entry.name, "Cant allocate ID for RO volume of %s\n"); - - entry.volumeId[ROVOL] = roVolId; - MapNetworkToHost(&entry, &storeEntry); - vcode = VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, 0); - ONERROR(vcode, entry.name, "Could not update vldb entry for %s.\n"); - } - - /* Will we be completing a previously unfinished release. -force overrides */ - for (fullrelease = 1, i = 0; (fullrelease && (i < entry.nServers)); i++) { - if (entry.serverFlags[i] & NEW_REPSITE) - fullrelease = 0; - } - if (forceflag && !fullrelease) - fullrelease = 1; - - /* Determine which volume id to use and see if it exists */ - cloneVolId = - ((fullrelease - || (entry.cloneId == 0)) ? entry.volumeId[ROVOL] : entry.cloneId); - code = VolumeExists(afromserver, afrompart, cloneVolId); - roexists = ((code == ENODEV) ? 0 : 1); - - fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT); - if (!fromconn) - ONERROR(-1, afromserver, - "Cannot establish connection with server 0x%x\n"); - - if (!fullrelease) { - if (!roexists) - fullrelease = 1; /* Do a full release if RO clone does not exist */ - else { - /* Begin transaction on RW and mark it busy while we query it */ - code = AFSVolTransCreate( - fromconn, afromvol, afrompart, ITBusy, &fromtid - ); - ONERROR(code, afromvol, - "Failed to start transaction on RW volume %u\n"); - - /* Query the creation date for the RW */ - code = AFSVolGetStatus(fromconn, fromtid, &volstatus); - ONERROR(code, afromvol, - "Failed to get the status of RW volume %u\n"); - rwcrdate = volstatus.creationDate; - - /* End transaction on RW */ - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - ONERROR((code ? code : rcode), afromvol, - "Failed to end transaction on RW volume %u\n"); - - /* Begin transaction on clone and mark it busy while we query it */ - code = AFSVolTransCreate( - fromconn, cloneVolId, afrompart, ITBusy, &clonetid - ); - ONERROR(code, cloneVolId, - "Failed to start transaction on RW clone %u\n"); - - /* Query the creation date for the clone */ - code = AFSVolGetStatus(fromconn, clonetid, &volstatus); - ONERROR(code, cloneVolId, - "Failed to get the status of RW clone %u\n"); - clcrdate = volstatus.creationDate; - - /* End transaction on RW */ - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - clonetid = 0; - ONERROR((code ? code : rcode), cloneVolId, - "Failed to end transaction on RW volume %u\n"); - - if (rwcrdate > clcrdate) - fullrelease = 2;/* Do a full release if RO clone older than RW */ - } - } - - if (verbose) { - switch (fullrelease) { - case 2: - fprintf(STDOUT, "RW %lu changed, doing a complete release\n", - (unsigned long)afromvol); - break; - case 1: - fprintf(STDOUT, "This is a complete release of volume %lu\n", - (unsigned long)afromvol); - break; - case 0: - fprintf(STDOUT, "This is a completion of a previous release\n"); - break; - } - } - - if (fullrelease) { - /* If the RO clone exists, then if the clone is a temporary - * clone, delete it. Or if the RO clone is marked RO_DONTUSE - * (it was recently added), then also delete it. We do not - * want to "reclone" a temporary RO clone. - */ - if (roexists - && (!roclone || (entry.serverFlags[roindex] & RO_DONTUSE))) { - code = DelVol(fromconn, cloneVolId, afrompart, ITOffline); - if (code && (code != VNOVOL)) - ERROREXIT(code); - roexists = 0; - } - - /* Mark all the ROs in the VLDB entry as RO_DONTUSE. We don't - * write this entry out to the vlserver until after the first - * RO volume is released (temp RO clones don't count). - */ - for (i = 0; i < entry.nServers; i++) { - entry.serverFlags[i] &= ~NEW_REPSITE; - entry.serverFlags[i] |= RO_DONTUSE; - } - entry.serverFlags[rwindex] |= NEW_REPSITE; - entry.serverFlags[rwindex] &= ~RO_DONTUSE; - - /* Begin transaction on RW and mark it busy while we clone it */ - code = - AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, - &clonetid); - ONERROR(code, afromvol, "Failed to start transaction on volume %u\n"); - - /* Clone or reclone the volume */ - if (roexists) { - VPRINT1("Recloning RW volume %u...", cloneVolId); - code = AFSVolReClone(fromconn, clonetid, cloneVolId); - ONERROR(code, afromvol, "Failed to reclone the RW volume %u\n"); - VDONE; - } else { - if (roclone) { - strcpy(vname, entry.name); - strcat(vname, ".readonly"); - VPRINT("Cloning RW volume %u to permanent RO..."); - } else { - strcpy(vname, "readonly-clone-temp"); - VPRINT("Cloning RW volume %u to temporary RO..."); - } - code = - AFSVolClone(fromconn, clonetid, 0, readonlyVolume, vname, - &cloneVolId); - ONERROR(code, afromvol, "Failed to clone the RW volume %u\n"); - VDONE; - } - - /* Get the time the RW was created for future information */ - VPRINT1("Getting status of RW volume %u...", cloneVolId); - code = AFSVolGetStatus(fromconn, clonetid, &volstatus); - ONERROR(code, cloneVolId, - "Failed to get the status of the RW volume %u\n"); - VDONE; - rwcrdate = volstatus.creationDate; - - /* End the transaction on the RW volume */ - VPRINT1("Ending cloning transaction on RW volume %u...", cloneVolId); - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - clonetid = 0; - ONERROR((code ? code : rcode), cloneVolId, - "Failed to end cloning transaction on RW %u\n"); - VDONE; - - /* Remember clone volume ID in case we fail or are interrupted */ - entry.cloneId = cloneVolId; - - if (roclone) { - /* Bring the RO clone online - though not if it's a temporary clone */ - VPRINT1("Starting transaction on RO clone volume %u...", - cloneVolId); - code = - AFSVolTransCreate(fromconn, cloneVolId, afrompart, ITOffline, - &onlinetid); - ONERROR(code, cloneVolId, - "Failed to start transaction on volume %u\n"); - VDONE; - - VPRINT1("Setting volume flags for volume %u...", cloneVolId); - tcode = AFSVolSetFlags(fromconn, onlinetid, 0); - VDONE; - - VPRINT1("Ending transaction on volume %u...", cloneVolId); - code = AFSVolEndTrans(fromconn, onlinetid, &rcode); - ONERROR((code ? code : rcode), cloneVolId, - "Failed to end transaction on RO clone %u\n"); - VDONE; - - ONERROR(tcode, cloneVolId, "Could not bring volume %u on line\n"); - - /* Sleep so that a client searching for an online volume won't - * find the clone offline and then the next RO offline while the - * release brings the clone online and the next RO offline (race). - * There is a fix in the 3.4 client that does not need this sleep - * anymore, but we don't know what clients we have. - */ - if (entry.nServers > 2) - sleep(5); - - /* Mark the RO clone in the VLDB as a good site (already released) */ - entry.serverFlags[roindex] |= NEW_REPSITE; - entry.serverFlags[roindex] &= ~RO_DONTUSE; - entry.flags |= RO_EXISTS; - - releasecount++; - - /* Write out the VLDB entry only if the clone is not a temporary - * clone. If we did this to a temporary clone then we would end - * up marking all the ROs as "old release" making the ROs - * temporarily unavailable. - */ - MapNetworkToHost(&entry, &storeEntry); - VPRINT1("Replacing VLDB entry for %s...", entry.name); - vcode = VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, 0); - ONERROR(vcode, entry.name, - "Could not update vldb entry for %s.\n"); - VDONE; - } - } - - /* Now we will release from the clone to the remaining RO replicas. - * The first 2 ROs (counting the non-temporary RO clone) are released - * individually: releasecount. This is to reduce the race condition - * of clients trying to find an on-line RO volume. The remaining ROs - * are released in parallel but no more than half the number of ROs - * (rounded up) at a time: nservers. - */ - - strcpy(vname, entry.name); - strcat(vname, ".readonly"); - memset(&cookie, 0, sizeof(cookie)); - strncpy(cookie.name, vname, VOLSER_OLDMAXVOLNAME); - cookie.type = ROVOL; - cookie.parent = entry.volumeId[RWVOL]; - cookie.clone = 0; - - nservers = entry.nServers / 2; /* how many to do at once, excluding clone */ - replicas = - (struct replica *)malloc(sizeof(struct replica) * nservers + 1); - times = (struct release *)malloc(sizeof(struct release) * nservers + 1); - toconns = - (struct rx_connection **)malloc(sizeof(struct rx_connection *) * - nservers + 1); - results.manyResults_val = - (afs_int32 *) malloc(sizeof(afs_int32) * nservers + 1); - if (!replicas || !times || !!!results.manyResults_val || !toconns) - ONERROR(ENOMEM, 0, - "Failed to create transaction on the release clone\n"); - - memset(replicas, 0, (sizeof(struct replica) * nservers + 1)); - memset(times, 0, (sizeof(struct release) * nservers + 1)); - memset(toconns, 0, (sizeof(struct rx_connection *) * nservers + 1)); - memset(results.manyResults_val, 0, (sizeof(afs_int32) * nservers + 1)); - - /* Create a transaction on the cloned volume */ - VPRINT1("Starting transaction on cloned volume %u...", cloneVolId); - code = - AFSVolTransCreate(fromconn, cloneVolId, afrompart, ITBusy, &fromtid); - if (!fullrelease && code) - ONERROR(VOLSERNOVOL, afromvol, - "Old clone is inaccessible. Try vos release -f %u.\n"); - ONERROR(code, 0, "Failed to create transaction on the release clone\n"); - VDONE; - - /* For each index in the VLDB */ - for (vldbindex = 0; vldbindex < entry.nServers;) { - - /* Get a transaction on the replicas. Pick replacas which have an old release. */ - for (volcount = 0; - ((volcount < nservers) && (vldbindex < entry.nServers)); - vldbindex++) { - /* The first two RO volumes will be released individually. - * The rest are then released in parallel. This is a hack - * for clients not recognizing right away when a RO volume - * comes back on-line. - */ - if ((volcount == 1) && (releasecount < 2)) - break; - - if (vldbindex == roindex) - continue; /* the clone */ - if ((entry.serverFlags[vldbindex] & NEW_REPSITE) - && !(entry.serverFlags[vldbindex] & RO_DONTUSE)) - continue; - if (!(entry.serverFlags[vldbindex] & ITSROVOL)) - continue; /* not a RO vol */ - - - /* Get a Transaction on this replica. Get a new connection if - * necessary. Create the volume if necessary. Return the - * time from which the dump should be made (0 if it's a new - * volume). Each volume might have a different time. - */ - replicas[volcount].server.destHost = - ntohl(entry.serverNumber[vldbindex]); - replicas[volcount].server.destPort = AFSCONF_VOLUMEPORT; - replicas[volcount].server.destSSID = 1; - times[volcount].vldbEntryIndex = vldbindex; - - code = - GetTrans(&entry, vldbindex, &(toconns[volcount]), - &(replicas[volcount].trans), - &(times[volcount].time)); - if (code) - continue; - - /* Thisdate is the date from which we want to pick up all changes */ - if (forceflag || !fullrelease - || (rwcrdate > times[volcount].time)) { - /* If the forceflag is set, then we want to do a full dump. - * If it's not a full release, we can't be sure that the creation - * date is good (so we also do a full dump). - * If the RW volume was replaced (its creation date is newer than - * the last release), then we can't be sure what has changed (so - * we do a full dump). - */ - thisdate = 0; - } else if (remembertime[vldbindex].validtime) { - /* Trans was prev ended. Use the time from the prev trans - * because, prev trans may have created the volume. In which - * case time[volcount].time would be now instead of 0. - */ - thisdate = - (remembertime[vldbindex].time < - times[volcount].time) ? remembertime[vldbindex]. - time : times[volcount].time; - } else { - thisdate = times[volcount].time; - } - remembertime[vldbindex].validtime = 1; - remembertime[vldbindex].time = thisdate; - - if (volcount == 0) { - fromdate = thisdate; - } else { - /* Include this volume if it is within 15 minutes of the earliest */ - if (((fromdate > - thisdate) ? (fromdate - thisdate) : (thisdate - - fromdate)) > 900) { - AFSVolEndTrans(toconns[volcount], - replicas[volcount].trans, &rcode); - replicas[volcount].trans = 0; - break; - } - if (thisdate < fromdate) - fromdate = thisdate; - } - volcount++; - } - if (!volcount) - continue; - - if (verbose) { - fprintf(STDOUT, "Starting ForwardMulti from %lu to %u on %s", - (unsigned long)cloneVolId, entry.volumeId[ROVOL], - hostutil_GetNameByINet(entry. - serverNumber[times[0]. - vldbEntryIndex])); - - for (s = 1; s < volcount; s++) { - fprintf(STDOUT, " and %s", - hostutil_GetNameByINet(entry. - serverNumber[times[s]. - vldbEntryIndex])); - } - - if (fromdate == 0) - fprintf(STDOUT, " (full release)"); - fprintf(STDOUT, ".\n"); - fflush(STDOUT); - } - - /* Release the ones we have collected */ - tr.manyDests_val = &(replicas[0]); - tr.manyDests_len = results.manyResults_len = volcount; - code = - AFSVolForwardMultiple(fromconn, fromtid, fromdate, &tr, - 0 /*spare */ , &cookie, &results); - if (code == RXGEN_OPCODE) { /* RPC Interface Mismatch */ - code = - SimulateForwardMultiple(fromconn, fromtid, fromdate, &tr, - 0 /*spare */ , &cookie, &results); - nservers = 1; - } - - if (code) { - PrintError("Release failed: ", code); - } else { - for (m = 0; m < volcount; m++) { - if (results.manyResults_val[m]) { - if ((m == 0) || (results.manyResults_val[m] != ENOENT)) { - /* we retry timed out transaction. When it is - * not the first volume and the transaction wasn't found - * (assume it timed out and was garbage collected by volser). - */ - PrintError - ("Failed to dump volume from clone to a ro site: ", - results.manyResults_val[m]); - } - continue; - } - - code = - AFSVolSetIdsTypes(toconns[m], replicas[m].trans, vname, - ROVOL, entry.volumeId[RWVOL], 0, 0); - if (code) { - if ((m == 0) || (code != ENOENT)) { - PrintError("Failed to set correct names and ids: ", - code); - } - continue; - } - - /* have to clear dest. flags to ensure new vol goes online: - * because the restore (forwarded) operation copied - * the V_inService(=0) flag over to the destination. - */ - code = AFSVolSetFlags(toconns[m], replicas[m].trans, 0); - if (code) { - if ((m == 0) || (code != ENOENT)) { - PrintError("Failed to set flags on ro volume: ", - code); - } - continue; - } - - entry.serverFlags[times[m].vldbEntryIndex] |= NEW_REPSITE; - entry.serverFlags[times[m].vldbEntryIndex] &= ~RO_DONTUSE; - entry.flags |= RO_EXISTS; - releasecount++; - } - } - - /* End the transactions and destroy the connections */ - for (s = 0; s < volcount; s++) { - if (replicas[s].trans) - code = AFSVolEndTrans(toconns[s], replicas[s].trans, &rcode); - replicas[s].trans = 0; - if (!code) - code = rcode; - if (code) { - if ((s == 0) || (code != ENOENT)) { - PrintError("Could not end transaction on a ro volume: ", - code); - } else { - PrintError - ("Transaction timed out on a ro volume. Will retry.\n", - 0); - if (times[s].vldbEntryIndex < vldbindex) - vldbindex = times[s].vldbEntryIndex; - } - } - - if (toconns[s]) - rx_DestroyConnection(toconns[s]); - toconns[s] = 0; - } - - MapNetworkToHost(&entry, &storeEntry); - vcode = VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, 0); - ONERROR(vcode, afromvol, - " Could not update VLDB entry for volume %u\n"); - } /* for each index in the vldb */ - - /* End the transaction on the cloned volume */ - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (!code) - code = rcode; - if (code) - PrintError("Failed to end transaction on rw volume: ", code); - - /* Figure out if any volume were not released and say so */ - for (failure = 0, i = 0; i < entry.nServers; i++) { - if (!(entry.serverFlags[i] & NEW_REPSITE)) - failure++; - } - if (failure) { - char pname[10]; - fprintf(STDERR, - "The volume %lu could not be released to the following %d sites:\n", - (unsigned long)afromvol, failure); - for (i = 0; i < entry.nServers; i++) { - if (!(entry.serverFlags[i] & NEW_REPSITE)) { - MapPartIdIntoName(entry.serverPartition[i], pname); - fprintf(STDERR, "\t%35s %s\n", - hostutil_GetNameByINet(entry.serverNumber[i]), pname); - } - } - - MapNetworkToHost(&entry, &storeEntry); - vcode = - VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, - LOCKREL_TIMESTAMP); - ONERROR(vcode, afromvol, - " Could not update VLDB entry for volume %u\n"); - - ERROREXIT(VOLSERBADRELEASE); - } - - /* All the ROs were release successfully. Remove the temporary clone */ - if (!roclone) { - if (verbose) { - fprintf(STDOUT, "Deleting the releaseClone %lu ...", - (unsigned long)cloneVolId); - fflush(STDOUT); - } - code = DelVol(fromconn, cloneVolId, afrompart, ITOffline); - ONERROR(code, cloneVolId, "Failed to delete volume %u.\n"); - VDONE; - } - entry.cloneId = 0; - - for (i = 0; i < entry.nServers; i++) - entry.serverFlags[i] &= ~NEW_REPSITE; - - /* Update the VLDB */ - VPRINT("updating VLDB ..."); - - MapNetworkToHost(&entry, &storeEntry); - vcode = - VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - ONERROR(vcode, afromvol, " Could not update VLDB entry for volume %u\n"); - VDONE; - - rfail: - if (clonetid) { - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - clonetid = 0; - if (code) { - fprintf(STDERR, - "Failed to end cloning transaction on the RW volume %lu\n", - (unsigned long)afromvol); - if (!error) - error = code; - } - } - if (fromtid) { - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (code) { - fprintf(STDERR, - "Failed to end transaction on the release clone %lu\n", - (unsigned long)cloneVolId); - if (!error) - error = code; - } - } - for (i = 0; i < nservers; i++) { - if (replicas && replicas[i].trans) { - code = AFSVolEndTrans(toconns[i], replicas[i].trans, &rcode); - replicas[i].trans = 0; - if (code) { - fprintf(STDERR, - "Failed to end transaction on ro volume %u at server %s\n", - entry.volumeId[ROVOL], - hostutil_GetNameByINet(htonl - (replicas[i].server. - destHost))); - if (!error) - error = code; - } - } - if (toconns && toconns[i]) { - rx_DestroyConnection(toconns[i]); - toconns[i] = 0; - } - } - if (islocked) { - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, RWVOL, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, - "Could not release lock on the VLDB entry for volume %lu\n", - (unsigned long)afromvol); - if (!error) - error = vcode; - } - } - - PrintError("", error); - - if (fromconn) - rx_DestroyConnection(fromconn); - if (results.manyResults_val) - free(results.manyResults_val); - if (replicas) - free(replicas); - if (toconns) - free(toconns); - if (times) - free(times); - return error; -} - - -void -dump_sig_handler(int x) -{ - fprintf(STDERR, "\nSignal handler: vos dump operation\n"); - longjmp(env, 0); -} - -/* Dump the volume on and - * to starting from . - * DumpFunction does the real work behind the scenes after - * extracting parameters from the rock - */ -int -UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart, - afs_int32 fromdate, afs_int32(*DumpFunction) (), char *rock) -{ - struct rx_connection *fromconn = (struct rx_connection *)0; - struct rx_call *fromcall = (struct rx_call *)0; - afs_int32 fromtid = 0, rxError = 0, rcode = 0; - afs_int32 code, error = 0; - - if (setjmp(env)) - ERROR_EXIT(EPIPE); -#ifndef AFS_NT40_ENV - (void)signal(SIGPIPE, dump_sig_handler); -#endif - (void)signal(SIGINT, dump_sig_handler); - - if (!fromdate) { - VPRINT("Full Dump ...\n"); - } else { - VPRINT1("Incremental Dump (as of %.24s)...\n", - ctime((time_t *) & fromdate)); - } - - /* get connections to the servers */ - fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT); - - VPRINT1("Starting transaction on volume %u...", afromvol); - code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid); - EGOTO1(error_exit, code, - "Could not start transaction on the volume %u to be dumped\n", - afromvol); - VDONE; - - fromcall = rx_NewCall(fromconn); - - VPRINT1("Starting volume dump on volume %u...", afromvol); - code = StartAFSVolDump(fromcall, fromtid, fromdate); - EGOTO(error_exit, code, "Could not start the dump process \n"); - VDONE; - - VPRINT1("Dumping volume %u...", afromvol); - code = DumpFunction(fromcall, rock); - EGOTO(error_exit, code, "Error while dumping volume \n"); - VDONE; - - error_exit: - if (fromcall) { - code = rx_EndCall(fromcall, rxError); - if (code) { - fprintf(STDERR, "Error in rx_EndCall\n"); - if (!error) - error = code; - } - } - if (fromtid) { - VPRINT1("Ending transaction on volume %u...", afromvol); - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - if (code || rcode) { - fprintf(STDERR, "Could not end transaction on the volume %lu\n", - (unsigned long)afromvol); - if (!error) - error = (code ? code : rcode); - } - VDONE; - } - if (fromconn) - rx_DestroyConnection(fromconn); - - PrintError("", error); - return (error); -} - -/* Clone the volume on and - * , and then dump the clone volume to - * starting from . - * DumpFunction does the real work behind the scenes after - * extracting parameters from the rock - */ -int -UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver, - afs_int32 afrompart, afs_int32 fromdate, - afs_int32(*DumpFunction) (), char *rock) -{ - struct rx_connection *fromconn = (struct rx_connection *)0; - struct rx_call *fromcall = (struct rx_call *)0; - afs_int32 fromtid = 0, rxError = 0, rcode = 0; - afs_int32 clonetid = 0; - afs_int32 code = 0, vcode = 0, error = 0; - afs_int32 clonevol = 0; - char vname[64]; - - if (setjmp(env)) - ERROR_EXIT(EPIPE); -#ifndef AFS_NT40_ENV - (void)signal(SIGPIPE, dump_sig_handler); -#endif - (void)signal(SIGINT, dump_sig_handler); - - if (!fromdate) { - VPRINT("Full Dump ...\n"); - } else { - VPRINT1("Incremental Dump (as of %.24s)...\n", - ctime((time_t *) & fromdate)); - } - - /* get connections to the servers */ - fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT); - - VPRINT1("Starting transaction on volume %u...", afromvol); - code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid); - EGOTO1(error_exit, code, - "Could not start transaction on the volume %u to be dumped\n", - afromvol); - VDONE; - - /* Get a clone id */ - VPRINT1("Allocating new volume id for clone of volume %u ...", afromvol); - code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &clonevol); - EGOTO1(error_exit, code, - "Could not get an ID for the clone of volume %u from the VLDB\n", - afromvol); - VDONE; - - /* Do the clone. Default flags on clone are set to delete on salvage and out of service */ - VPRINT2("Cloning source volume %u to clone volume %u...", afromvol, - clonevol); - strcpy(vname, "dump-clone-temp"); - code = - AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &clonevol); - EGOTO1(error_exit, code, "Failed to clone the source volume %u\n", - afromvol); - VDONE; - - VPRINT1("Ending the transaction on the volume %u ...", afromvol); - rcode = 0; - code = AFSVolEndTrans(fromconn, fromtid, &rcode); - fromtid = 0; - if (!code) - code = rcode; - EGOTO1(error_exit, code, - "Failed to end the transaction on the volume %u\n", afromvol); - VDONE; - - - VPRINT1("Starting transaction on the cloned volume %u ...", clonevol); - code = - AFSVolTransCreate(fromconn, clonevol, afrompart, ITOffline, - &clonetid); - EGOTO1(error_exit, code, - "Failed to start a transaction on the cloned volume%u\n", - clonevol); - VDONE; - - VPRINT1("Setting flags on cloned volume %u ...", clonevol); - code = AFSVolSetFlags(fromconn, clonetid, VTDeleteOnSalvage | VTOutOfService); /*redundant */ - EGOTO1(error_exit, code, "Could not set falgs on the cloned volume %u\n", - clonevol); - VDONE; - - - fromcall = rx_NewCall(fromconn); - - VPRINT1("Starting volume dump from cloned volume %u...", clonevol); - code = StartAFSVolDump(fromcall, clonetid, fromdate); - EGOTO(error_exit, code, "Could not start the dump process \n"); - VDONE; - - VPRINT1("Dumping volume %u...", afromvol); - code = DumpFunction(fromcall, rock); - EGOTO(error_exit, code, "Error while dumping volume \n"); - VDONE; - - error_exit: - /* now delete the clone */ - VPRINT1("Deleting the cloned volume %u ...", clonevol); - code = AFSVolDeleteVolume(fromconn, clonetid); - if (code) { - fprintf(STDERR, "Failed to delete the cloned volume %lu\n", - (unsigned long)clonevol); - } else { - VDONE; - } - - if (fromcall) { - code = rx_EndCall(fromcall, rxError); - if (code) { - fprintf(STDERR, "Error in rx_EndCall\n"); - if (!error) - error = code; - } - } - if (clonetid) { - VPRINT1("Ending transaction on cloned volume %u...", clonevol); - code = AFSVolEndTrans(fromconn, clonetid, &rcode); - if (code || rcode) { - fprintf(STDERR, - "Could not end transaction on the cloned volume %lu\n", - (unsigned long)clonevol); - if (!error) - error = (code ? code : rcode); - } - VDONE; - } - if (fromconn) - rx_DestroyConnection(fromconn); - - PrintError("", error); - return (error); -} - - - -/* - * Restore a volume on from - * the dump file . WriteData does all the real work - * after extracting params from the rock - */ -int -UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid, - char tovolname[], int flags, afs_int32(*WriteData) (), - char *rock) -{ - struct rx_connection *toconn, *tempconn; - struct rx_call *tocall; - afs_int32 totid, code, rcode, vcode, terror = 0; - afs_int32 rxError = 0; - struct volser_status tstatus; - char partName[10]; - afs_int32 pvolid; - afs_int32 temptid; - int success; - struct nvldbentry entry, storeEntry; - afs_int32 error; - int islocked; - struct restoreCookie cookie; - int reuseID; - afs_int32 newDate, volflag, voltype, volsertype; - int index, same, errcode; - char apartName[10]; - - - memset(&cookie, 0, sizeof(cookie)); - islocked = 0; - success = 0; - error = 0; - reuseID = 1; - tocall = (struct rx_call *)0; - toconn = (struct rx_connection *)0; - tempconn = (struct rx_connection *)0; - totid = 0; - temptid = 0; - - if (flags & RV_RDONLY) { - voltype = ROVOL; - volsertype = volser_RO; - } else { - voltype = RWVOL; - volsertype = volser_RW; - } - - pvolid = tovolid; - toconn = UV_Bind(toserver, AFSCONF_VOLUMEPORT); - if (pvolid == 0) { /*alot a new id if needed */ - vcode = VLDB_GetEntryByName(tovolname, &entry); - if (vcode == VL_NOENT) { - vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &pvolid); - if (vcode) { - fprintf(STDERR, "Could not get an Id for the volume %s\n", - tovolname); - error = vcode; - goto refail; - } - reuseID = 0; - } else if (flags & RV_RDONLY) { - if (entry.flags & RW_EXISTS) { - fprintf(STDERR, - "Entry for ReadWrite volume %s already exists!\n", - entry.name); - error = VOLSERBADOP; - goto refail; - } - if (!entry.volumeId[ROVOL]) { - fprintf(STDERR, - "Existing entry for volume %s has no ReadOnly ID\n", - tovolname); - error = VOLSERBADOP; - goto refail; - } - pvolid = entry.volumeId[ROVOL]; - } else { - pvolid = entry.volumeId[RWVOL]; - } - } - /* at this point we have a volume id to use/reuse for the volume to be restored */ - if (strlen(tovolname) > (VOLSER_OLDMAXVOLNAME - 1)) { - EGOTO1(refail, VOLSERBADOP, - "The volume name %s exceeds the maximum limit of (VOLSER_OLDMAXVOLNAME -1 ) bytes\n", - tovolname); - } - MapPartIdIntoName(topart, partName); - fprintf(STDOUT, "Restoring volume %s Id %lu on server %s partition %s ..", - tovolname, (unsigned long)pvolid, - hostutil_GetNameByINet(toserver), partName); - fflush(STDOUT); - code = - AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0, &pvolid, - &totid); - if (code) { - if (flags & RV_FULLRST) { /* full restore: delete then create anew */ - VPRINT1("Deleting the previous volume %u ...", pvolid); - - code = - AFSVolTransCreate(toconn, pvolid, topart, ITOffline, &totid); - EGOTO1(refail, code, "Failed to start transaction on %u\n", - pvolid); - - code = - AFSVolSetFlags(toconn, totid, - VTDeleteOnSalvage | VTOutOfService); - EGOTO1(refail, code, "Could not set flags on volume %u \n", - pvolid); - - code = AFSVolDeleteVolume(toconn, totid); - EGOTO1(refail, code, "Could not delete volume %u\n", pvolid); - - code = AFSVolEndTrans(toconn, totid, &rcode); - totid = 0; - if (!code) - code = rcode; - EGOTO1(refail, code, "Could not end transaction on %u\n", pvolid); - - VDONE; - - code = - AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0, - &pvolid, &totid); - EGOTO1(refail, code, "Could not create new volume %u\n", pvolid); - - newDate = 0; - } else { - code = - AFSVolTransCreate(toconn, pvolid, topart, ITOffline, &totid); - EGOTO1(refail, code, "Failed to start transaction on %u\n", - pvolid); - - code = AFSVolGetStatus(toconn, totid, &tstatus); - EGOTO1(refail, code, "Could not get timestamp from volume %u\n", - pvolid); - newDate = tstatus.creationDate; - } - } - cookie.parent = pvolid; - cookie.type = voltype; - cookie.clone = 0; - strncpy(cookie.name, tovolname, VOLSER_OLDMAXVOLNAME); - - tocall = rx_NewCall(toconn); - terror = StartAFSVolRestore(tocall, totid, 1, &cookie); - if (terror) { - fprintf(STDERR, "Volume restore Failed \n"); - error = terror; - goto refail; - } - code = WriteData(tocall, rock); - if (code) { - fprintf(STDERR, "Could not transmit data\n"); - error = code; - goto refail; - } - terror = rx_EndCall(tocall, rxError); - tocall = (struct rx_call *)0; - if (terror) { - fprintf(STDERR, "rx_EndCall Failed \n"); - error = terror; - goto refail; - } - code = AFSVolGetStatus(toconn, totid, &tstatus); - if (code) { - fprintf(STDERR, - "Could not get status information about the volume %lu\n", - (unsigned long)pvolid); - error = code; - goto refail; - } - code = AFSVolSetIdsTypes(toconn, totid, tovolname, voltype, pvolid, 0, 0); - if (code) { - fprintf(STDERR, "Could not set the right type and ID on %lu\n", - (unsigned long)pvolid); - error = code; - goto refail; - } - if (!newDate) - newDate = time(0); - code = AFSVolSetDate(toconn, totid, newDate); - if (code) { - fprintf(STDERR, "Could not set the date on %lu\n", - (unsigned long)pvolid); - error = code; - goto refail; - } - - volflag = ((flags & RV_OFFLINE) ? VTOutOfService : 0); /* off or on-line */ - code = AFSVolSetFlags(toconn, totid, volflag); - if (code) { - fprintf(STDERR, "Could not mark %lu online\n", (unsigned long)pvolid); - error = code; - goto refail; - } - -/* It isn't handled right in refail */ - code = AFSVolEndTrans(toconn, totid, &rcode); - totid = 0; - if (!code) - code = rcode; - if (code) { - fprintf(STDERR, "Could not end transaction on %lu\n", - (unsigned long)pvolid); - error = code; - goto refail; - } - - success = 1; - fprintf(STDOUT, " done\n"); - fflush(STDOUT); - if (success && (!reuseID || (flags & RV_FULLRST))) { - /* Volume was restored on the file server, update the - * VLDB to reflect the change. - */ - vcode = VLDB_GetEntryByID(pvolid, voltype, &entry); - if (vcode && vcode != VL_NOENT && vcode != VL_ENTDELETED) { - fprintf(STDERR, - "Could not fetch the entry for volume number %lu from VLDB \n", - (unsigned long)pvolid); - error = vcode; - goto refail; - } - if (!vcode) - MapHostToNetwork(&entry); - if (vcode == VL_NOENT) { /* it doesnot exist already */ - /*make the vldb return this indication specifically */ - VPRINT("------- Creating a new VLDB entry ------- \n"); - strcpy(entry.name, tovolname); - entry.nServers = 1; - entry.serverNumber[0] = toserver; /*should be indirect */ - entry.serverPartition[0] = topart; - entry.serverFlags[0] = (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL; - entry.flags = (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS; - if (flags & RV_RDONLY) - entry.volumeId[ROVOL] = pvolid; - else if (tstatus.cloneID != 0) { - entry.volumeId[ROVOL] = tstatus.cloneID; /*this should come from status info on the volume if non zero */ - } else - entry.volumeId[ROVOL] = INVALID_BID; - entry.volumeId[RWVOL] = pvolid; - entry.cloneId = 0; - if (tstatus.backupID != 0) { - entry.volumeId[BACKVOL] = tstatus.backupID; - /*this should come from status info on the volume if non zero */ - } else - entry.volumeId[BACKVOL] = INVALID_BID; - MapNetworkToHost(&entry, &storeEntry); - vcode = VLDB_CreateEntry(&storeEntry); - if (vcode) { - fprintf(STDERR, - "Could not create the VLDB entry for volume number %lu \n", - (unsigned long)pvolid); - error = vcode; - goto refail; - } - islocked = 0; - if (verbose) - EnumerateEntry(&entry); - } else { /*update the existing entry */ - if (verbose) { - fprintf(STDOUT, "Updating the existing VLDB entry\n"); - fprintf(STDOUT, "------- Old entry -------\n"); - EnumerateEntry(&entry); - fprintf(STDOUT, "------- New entry -------\n"); - } - vcode = - ubik_Call(VL_SetLock, cstruct, 0, pvolid, voltype, - VLOP_RESTORE); - if (vcode) { - fprintf(STDERR, - "Could not lock the entry for volume number %lu \n", - (unsigned long)pvolid); - error = vcode; - goto refail; - } - islocked = 1; - strcpy(entry.name, tovolname); - - /* Update the vlentry with the new information */ - if (flags & RV_RDONLY) - index = Lp_ROMatch(toserver, topart, &entry) - 1; - else - index = Lp_GetRwIndex(&entry); - if (index == -1) { - /* Add the new site for the volume being restored */ - entry.serverNumber[entry.nServers] = toserver; - entry.serverPartition[entry.nServers] = topart; - entry.serverFlags[entry.nServers] = - (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL; - entry.nServers++; - } else { - /* This volume should be deleted on the old site - * if its different from new site. - */ - same = - VLDB_IsSameAddrs(toserver, entry.serverNumber[index], - &errcode); - EPRINT2(errcode, - "Failed to get info about server's %d address(es) from vlserver (err=%d)\n", - toserver, errcode); - if ((!errcode && !same) - || (entry.serverPartition[index] != topart)) { - tempconn = - UV_Bind(entry.serverNumber[index], - AFSCONF_VOLUMEPORT); - - MapPartIdIntoName(entry.serverPartition[index], - apartName); - VPRINT3 - ("Deleting the previous volume %u on server %s, partition %s ...", - pvolid, - hostutil_GetNameByINet(entry.serverNumber[index]), - apartName); - code = - AFSVolTransCreate(tempconn, pvolid, - entry.serverPartition[index], - ITOffline, &temptid); - if (!code) { - code = - AFSVolSetFlags(tempconn, temptid, - VTDeleteOnSalvage | - VTOutOfService); - if (code) { - fprintf(STDERR, - "Could not set flags on volume %lu on the older site\n", - (unsigned long)pvolid); - error = code; - goto refail; - } - code = AFSVolDeleteVolume(tempconn, temptid); - if (code) { - fprintf(STDERR, - "Could not delete volume %lu on the older site\n", - (unsigned long)pvolid); - error = code; - goto refail; - } - code = AFSVolEndTrans(tempconn, temptid, &rcode); - temptid = 0; - if (!code) - code = rcode; - if (code) { - fprintf(STDERR, - "Could not end transaction on volume %lu on the older site\n", - (unsigned long)pvolid); - error = code; - goto refail; - } - VDONE; - MapPartIdIntoName(entry.serverPartition[index], - partName); - } - } - entry.serverNumber[index] = toserver; - entry.serverPartition[index] = topart; - } - - entry.flags |= (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS; - MapNetworkToHost(&entry, &storeEntry); - vcode = - VLDB_ReplaceEntry(pvolid, voltype, &storeEntry, - LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, - "Could not update the entry for volume number %lu \n", - (unsigned long)pvolid); - error = vcode; - goto refail; - } - islocked = 0; - if (verbose) - EnumerateEntry(&entry); - } - - - } - refail: - if (tocall) { - code = rx_EndCall(tocall, rxError); - if (!error) - error = code; - } - if (islocked) { - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, pvolid, voltype, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, - "Could not release lock on the VLDB entry for the volume %lu\n", - (unsigned long)pvolid); - if (!error) - error = vcode; - } - } - if (totid) { - code = AFSVolEndTrans(toconn, totid, &rcode); - if (!code) - code = rcode; - if (code) { - fprintf(STDERR, "Could not end transaction on the volume %lu \n", - (unsigned long)pvolid); - if (!error) - error = code; - } - } - if (temptid) { - code = AFSVolEndTrans(toconn, temptid, &rcode); - if (!code) - code = rcode; - if (code) { - fprintf(STDERR, "Could not end transaction on the volume %lu \n", - (unsigned long)pvolid); - if (!error) - error = code; - } - } - if (tempconn) - rx_DestroyConnection(tempconn); - if (toconn) - rx_DestroyConnection(toconn); - PrintError("", error); - return error; -} - - -/*unlocks the vldb entry associated with */ -int -UV_LockRelease(afs_int32 volid) -{ - - - afs_int32 vcode; - - VPRINT("Binding to the VLDB server\n"); - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, volid, -1, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, - "Could not unlock the entry for volume number %lu in VLDB \n", - (unsigned long)volid); - PrintError("", vcode); - return (vcode); - } - VPRINT("VLDB updated\n"); - return 0; - -} - -/*adds and as a readonly replication site for -*in vldb */ -int -UV_AddSite(afs_int32 server, afs_int32 part, afs_int32 volid) -{ - int j, nro = 0, islocked = 0; - struct nvldbentry entry, storeEntry; - afs_int32 vcode, error = 0; - char apartName[10]; - - error = ubik_Call(VL_SetLock, cstruct, 0, volid, RWVOL, VLOP_ADDSITE); - if (error) { - fprintf(STDERR, - " Could not lock the VLDB entry for the volume %lu \n", - (unsigned long)volid); - goto asfail; - } - islocked = 1; - - error = VLDB_GetEntryByID(volid, RWVOL, &entry); - if (error) { - fprintf(STDERR, - "Could not fetch the VLDB entry for volume number %lu \n", - (unsigned long)volid); - goto asfail; - - } - if (!ISNAMEVALID(entry.name)) { - fprintf(STDERR, - "Volume name %s is too long, rename before adding site\n", - entry.name); - error = VOLSERBADOP; - goto asfail; - } - MapHostToNetwork(&entry); - - /* See if it's too many entries */ - if (entry.nServers >= NMAXNSERVERS) { - fprintf(STDERR, "Total number of entries will exceed %u\n", - NMAXNSERVERS); - error = VOLSERBADOP; - goto asfail; - } - - /* See if it's on the same server */ - for (j = 0; j < entry.nServers; j++) { - if (entry.serverFlags[j] & ITSROVOL) { - nro++; - if (VLDB_IsSameAddrs(server, entry.serverNumber[j], &error)) { - if (error) { - fprintf(STDERR, - "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n", - server, error); - } else { - MapPartIdIntoName(entry.serverPartition[j], apartName); - fprintf(STDERR, - "RO already exists on partition %s. Multiple ROs on a single server aren't allowed\n", - apartName); - error = VOLSERBADOP; - } - goto asfail; - } - } - } - - /* See if it's too many RO sites - leave one for the RW */ - if (nro >= NMAXNSERVERS - 1) { - fprintf(STDERR, "Total number of sites will exceed %u\n", - NMAXNSERVERS - 1); - error = VOLSERBADOP; - goto asfail; - } - - VPRINT("Adding a new site ..."); - entry.serverNumber[entry.nServers] = server; - entry.serverPartition[entry.nServers] = part; - entry.serverFlags[entry.nServers] = (ITSROVOL | RO_DONTUSE); - entry.nServers++; - - MapNetworkToHost(&entry, &storeEntry); - error = - VLDB_ReplaceEntry(volid, RWVOL, &storeEntry, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (error) { - fprintf(STDERR, "Could not update entry for volume %lu \n", - (unsigned long)volid); - goto asfail; - } - islocked = 0; - VDONE; - - asfail: - if (islocked) { - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, - "Could not release lock on volume entry for %lu \n", - (unsigned long)volid); - PrintError("", vcode); - } - } - - PrintError("", error); - return error; -} - -/*removes as read only site for from the vldb */ -int -UV_RemoveSite(afs_int32 server, afs_int32 part, afs_int32 volid) -{ - afs_int32 vcode; - struct nvldbentry entry, storeEntry; - int islocked; - - vcode = ubik_Call(VL_SetLock, cstruct, 0, volid, RWVOL, VLOP_ADDSITE); - if (vcode) { - fprintf(STDERR, " Could not lock the VLDB entry for volume %lu \n", - (unsigned long)volid); - PrintError("", vcode); - return (vcode); - } - islocked = 1; - vcode = VLDB_GetEntryByID(volid, RWVOL, &entry); - if (vcode) { - fprintf(STDERR, - "Could not fetch the entry for volume number %lu from VLDB \n", - (unsigned long)volid); - PrintError("", vcode); - return (vcode); - } - MapHostToNetwork(&entry); - if (!Lp_ROMatch(server, part, &entry)) { - /*this site doesnot exist */ - fprintf(STDERR, "This site is not a replication site \n"); - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, "Could not update entry for volume %lu \n", - (unsigned long)volid); - PrintError("", vcode); - ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - return (vcode); - } - return VOLSERBADOP; - } else { /*remove the rep site */ - Lp_SetROValue(&entry, server, part, 0, 0); - entry.nServers--; - if ((entry.nServers == 1) && (entry.flags & RW_EXISTS)) - entry.flags &= ~RO_EXISTS; - if (entry.nServers < 1) { /*this is the last ref */ - VPRINT1("Deleting the VLDB entry for %u ...", volid); - fflush(STDOUT); - vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, volid, ROVOL); - if (vcode) { - fprintf(STDERR, - "Could not delete VLDB entry for volume %lu \n", - (unsigned long)volid); - PrintError("", vcode); - return (vcode); - } - VDONE; - } - MapNetworkToHost(&entry, &storeEntry); - fprintf(STDOUT, "Deleting the replication site for volume %lu ...", - (unsigned long)volid); - fflush(STDOUT); - vcode = - VLDB_ReplaceEntry(volid, RWVOL, &storeEntry, - LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, - "Could not release lock on volume entry for %lu \n", - (unsigned long)volid); - PrintError("", vcode); - ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - return (vcode); - } - VDONE; - } - return 0; -} - -/*sets as read/write site for in the vldb */ -int -UV_ChangeLocation(afs_int32 server, afs_int32 part, afs_int32 volid) -{ - afs_int32 vcode; - struct nvldbentry entry, storeEntry; - int index; - - vcode = ubik_Call(VL_SetLock, cstruct, 0, volid, RWVOL, VLOP_ADDSITE); - if (vcode) { - fprintf(STDERR, " Could not lock the VLDB entry for volume %lu \n", - (unsigned long)volid); - PrintError("", vcode); - return (vcode); - } - vcode = VLDB_GetEntryByID(volid, RWVOL, &entry); - if (vcode) { - fprintf(STDERR, - "Could not fetch the entry for volume number %lu from VLDB \n", - (unsigned long)volid); - PrintError("", vcode); - return (vcode); - } - MapHostToNetwork(&entry); - index = Lp_GetRwIndex(&entry); - if (index < 0) { - /* no RW site exists */ - fprintf(STDERR, "No existing RW site for volume %lu", - (unsigned long)volid); - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, - "Could not release lock on entry for volume %lu \n", - (unsigned long)volid); - PrintError("", vcode); - return (vcode); - } - return VOLSERBADOP; - } else { /* change the RW site */ - entry.serverNumber[index] = server; - entry.serverPartition[index] = part; - MapNetworkToHost(&entry, &storeEntry); - vcode = - VLDB_ReplaceEntry(volid, RWVOL, &storeEntry, - LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, "Could not update entry for volume %lu \n", - (unsigned long)volid); - PrintError("", vcode); - ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - return (vcode); - } - VDONE; - } - return 0; -} - -/*list all the partitions on */ -int -UV_ListPartitions(afs_int32 aserver, struct partList *ptrPartList, - afs_int32 * cntp) -{ - struct rx_connection *aconn; - struct pIDs partIds; - struct partEntries partEnts; - register int i, j = 0, code; - - *cntp = 0; - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - - partEnts.partEntries_len = 0; - partEnts.partEntries_val = NULL; - code = AFSVolXListPartitions(aconn, &partEnts); /* this is available only on new servers */ - if (code == RXGEN_OPCODE) { - for (i = 0; i < 26; i++) /* try old interface */ - partIds.partIds[i] = -1; - code = AFSVolListPartitions(aconn, &partIds); - if (!code) { - for (i = 0; i < 26; i++) { - if ((partIds.partIds[i]) != -1) { - ptrPartList->partId[j] = partIds.partIds[i]; - ptrPartList->partFlags[j] = PARTVALID; - j++; - } else - ptrPartList->partFlags[i] = 0; - } - *cntp = j; - } - } else if (!code) { - *cntp = partEnts.partEntries_len; - if (*cntp > VOLMAXPARTS) { - fprintf(STDERR, - "Warning: number of partitions on the server too high %d (process only %d)\n", - *cntp, VOLMAXPARTS); - *cntp = VOLMAXPARTS; - } - for (i = 0; i < *cntp; i++) { - ptrPartList->partId[i] = partEnts.partEntries_val[i]; - ptrPartList->partFlags[i] = PARTVALID; - } - free(partEnts.partEntries_val); - } - - /* out: */ - if (code) - fprintf(STDERR, - "Could not fetch the list of partitions from the server\n"); - PrintError("", code); - if (aconn) - rx_DestroyConnection(aconn); - return code; -} - - -/*zap the list of volumes specified by volPtrArray (the volCloneId field). - This is used by the backup system */ -int -UV_ZapVolumeClones(afs_int32 aserver, afs_int32 apart, - struct volDescription *volPtr, afs_int32 arraySize) -{ - struct rx_connection *aconn; - struct volDescription *curPtr; - int curPos; - afs_int32 code = 0; - afs_int32 rcode = 0; - afs_int32 success = 1; - afs_int32 tid; - - aconn = (struct rx_connection *)0; - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - curPos = 0; - for (curPtr = volPtr; curPos < arraySize; curPtr++) { - if (curPtr->volFlags & CLONEVALID) { - curPtr->volFlags &= ~CLONEZAPPED; - success = 1; - code = - AFSVolTransCreate(aconn, curPtr->volCloneId, apart, ITOffline, - &tid); - if (code) - success = 0; - else { - code = AFSVolDeleteVolume(aconn, tid); - if (code) - success = 0; - code = AFSVolEndTrans(aconn, tid, &rcode); - if (code || rcode) - success = 0; - } - if (success) - curPtr->volFlags |= CLONEZAPPED; - if (!success) - fprintf(STDERR, "Could not zap volume %lu\n", - (unsigned long)curPtr->volCloneId); - if (success) - VPRINT2("Clone of %s %u deleted\n", curPtr->volName, - curPtr->volCloneId); - curPos++; - tid = 0; - } - } - if (aconn) - rx_DestroyConnection(aconn); - return 0; -} - -/*return a list of clones of the volumes specified by volPtrArray. Used by the - backup system */ -int -UV_GenerateVolumeClones(afs_int32 aserver, afs_int32 apart, - struct volDescription *volPtr, afs_int32 arraySize) -{ - struct rx_connection *aconn; - struct volDescription *curPtr; - int curPos; - afs_int32 code = 0; - afs_int32 rcode = 0; - afs_int32 tid; - int reuseCloneId = 0; - afs_int32 curCloneId = 0; - char cloneName[256]; /*max vol name */ - - aconn = (struct rx_connection *)0; - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - curPos = 0; - if ((volPtr->volFlags & REUSECLONEID) && (volPtr->volFlags & ENTRYVALID)) - reuseCloneId = 1; - else { /*get a bunch of id's from vldb */ - code = - ubik_Call(VL_GetNewVolumeId, cstruct, 0, arraySize, &curCloneId); - if (code) { - fprintf(STDERR, "Could not get ID's for the clone from VLDB\n"); - PrintError("", code); - return code; - } - } - - for (curPtr = volPtr; curPos < arraySize; curPtr++) { - if (curPtr->volFlags & ENTRYVALID) { - - curPtr->volFlags |= CLONEVALID; - /*make a clone of curParentId and record as curPtr->volCloneId */ - code = - AFSVolTransCreate(aconn, curPtr->volId, apart, ITOffline, - &tid); - if (code) - VPRINT2("Clone for volume %s %u failed \n", curPtr->volName, - curPtr->volId); - if (code) { - curPtr->volFlags &= ~CLONEVALID; /*cant clone */ - curPos++; - continue; - } - if (strlen(curPtr->volName) < (VOLSER_OLDMAXVOLNAME - 9)) { - strcpy(cloneName, curPtr->volName); - strcat(cloneName, "-tmpClone-"); - } else - strcpy(cloneName, "-tmpClone"); - if (reuseCloneId) { - curPtr->volCloneId = curCloneId; - curCloneId++; - } - - code = - AFSVolClone(aconn, tid, 0, readonlyVolume, cloneName, - &(curPtr->volCloneId)); - if (code) { - curPtr->volFlags &= ~CLONEVALID; - curPos++; - fprintf(STDERR, "Could not clone %s due to error %lu\n", - curPtr->volName, (unsigned long)code); - code = AFSVolEndTrans(aconn, tid, &rcode); - if (code) - fprintf(STDERR, "WARNING: could not end transaction\n"); - continue; - } - VPRINT2("********** Cloned %s temporary %u\n", cloneName, - curPtr->volCloneId); - code = AFSVolEndTrans(aconn, tid, &rcode); - if (code || rcode) { - curPtr->volFlags &= ~CLONEVALID; - curPos++; - continue; - } - - curPos++; - } - } - if (aconn) - rx_DestroyConnection(aconn); - return 0; -} - - -/*list all the volumes on and . If all = 1, then all the -* relevant fields of the volume are also returned. This is a heavy weight operation.*/ -int -UV_ListVolumes(afs_int32 aserver, afs_int32 apart, int all, - struct volintInfo **resultPtr, afs_int32 * size) -{ - struct rx_connection *aconn; - afs_int32 code = 0; - volEntries volumeInfo; - - code = 0; - *size = 0; - *resultPtr = (volintInfo *) 0; - volumeInfo.volEntries_val = (volintInfo *) 0; /*this hints the stub to allocate space */ - volumeInfo.volEntries_len = 0; - - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - code = AFSVolListVolumes(aconn, apart, all, &volumeInfo); - if (code) { - fprintf(STDERR, - "Could not fetch the list of volumes from the server\n"); - } else { - *resultPtr = volumeInfo.volEntries_val; - *size = volumeInfo.volEntries_len; - } - - if (aconn) - rx_DestroyConnection(aconn); - PrintError("", code); - return code; -} - -/*------------------------------------------------------------------------ - * EXPORTED UV_XListVolumes - * - * Description: - * List the extended information for all the volumes on a particular - * File Server and partition. We may either return the volume's ID - * or all of its extended information. - * - * Arguments: - * a_serverID : Address of the File Server for which we want - * extended volume info. - * a_partID : Partition for which we want the extended - * volume info. - * a_all : If non-zero, fetch ALL the volume info, - * otherwise just the volume ID. - * a_resultPP : Ptr to the address of the area containing - * the returned volume info. - * a_numEntsInResultP : Ptr for the value we set for the number of - * entries returned. - * - * Returns: - * 0 on success, - * Otherise, the return value of AFSVolXListVolumes. - * - * Environment: - * This routine is closely related to UV_ListVolumes, which returns - * only the standard level of detail on AFS volumes. It is a - * heavyweight operation, zipping through all the volume entries for - * a given server/partition. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -int -UV_XListVolumes(afs_int32 a_serverID, afs_int32 a_partID, int a_all, - struct volintXInfo **a_resultPP, - afs_int32 * a_numEntsInResultP) -{ - struct rx_connection *rxConnP; /*Ptr to the Rx connection involved */ - afs_int32 code; /*Error code to return */ - volXEntries volumeXInfo; /*Area for returned extended vol info */ - - /* - * Set up our error code and the area for returned extended volume info. - * We set the val field to a null pointer as a hint for the stub to - * allocate space. - */ - code = 0; - *a_numEntsInResultP = 0; - *a_resultPP = (volintXInfo *) 0; - volumeXInfo.volXEntries_val = (volintXInfo *) 0; - volumeXInfo.volXEntries_len = 0; - - /* - * Bind to the Volume Server port on the File Server machine in question, - * then go for it. - */ - rxConnP = UV_Bind(a_serverID, AFSCONF_VOLUMEPORT); - code = AFSVolXListVolumes(rxConnP, a_partID, a_all, &volumeXInfo); - if (code) - fprintf(STDERR, "[UV_XListVolumes] Couldn't fetch volume list\n"); - else { - /* - * We got the info; pull out the pointer to where the results lie - * and how many entries are there. - */ - *a_resultPP = volumeXInfo.volXEntries_val; - *a_numEntsInResultP = volumeXInfo.volXEntries_len; - } - - /* - * If we got an Rx connection, throw it away. - */ - if (rxConnP) - rx_DestroyConnection(rxConnP); - - PrintError("", code); - return (code); -} /*UV_XListVolumes */ - -/* get all the information about volume on and */ -int -UV_ListOneVolume(afs_int32 aserver, afs_int32 apart, afs_int32 volid, - struct volintInfo **resultPtr) -{ - struct rx_connection *aconn; - afs_int32 code = 0; - volEntries volumeInfo; - - code = 0; - - *resultPtr = (volintInfo *) 0; - volumeInfo.volEntries_val = (volintInfo *) 0; /*this hints the stub to allocate space */ - volumeInfo.volEntries_len = 0; - - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - code = AFSVolListOneVolume(aconn, apart, volid, &volumeInfo); - if (code) { - fprintf(STDERR, - "Could not fetch the information about volume %lu from the server\n", - (unsigned long)volid); - } else { - *resultPtr = volumeInfo.volEntries_val; - - } - - if (aconn) - rx_DestroyConnection(aconn); - PrintError("", code); - return code; -} - -/*------------------------------------------------------------------------ - * EXPORTED UV_XListOneVolume - * - * Description: - * List the extended information for a volume on a particular File - * Server and partition. - * - * Arguments: - * a_serverID : Address of the File Server for which we want - * extended volume info. - * a_partID : Partition for which we want the extended - * volume info. - * a_volID : Volume ID for which we want the info. - * a_resultPP : Ptr to the address of the area containing - * the returned volume info. - * - * Returns: - * 0 on success, - * Otherise, the return value of AFSVolXListOneVolume. - * - * Environment: - * This routine is closely related to UV_ListOneVolume, which returns - * only the standard level of detail on the chosen AFS volume. - * - * Side Effects: - * As advertised. - *------------------------------------------------------------------------*/ - -int -UV_XListOneVolume(afs_int32 a_serverID, afs_int32 a_partID, afs_int32 a_volID, - struct volintXInfo **a_resultPP) -{ - struct rx_connection *rxConnP; /*Rx connection to Volume Server */ - afs_int32 code; /*Error code */ - volXEntries volumeXInfo; /*Area for returned info */ - - /* - * Set up our error code, and the area we're in which we are returning - * the info. Setting the val field to a null pointer tells the stub - * to allocate space for us. - */ - code = 0; - *a_resultPP = (volintXInfo *) 0; - volumeXInfo.volXEntries_val = (volintXInfo *) 0; - volumeXInfo.volXEntries_len = 0; - - /* - * Bind to the Volume Server port on the File Server machine in question, - * then go for it. - */ - rxConnP = UV_Bind(a_serverID, AFSCONF_VOLUMEPORT); - code = AFSVolXListOneVolume(rxConnP, a_partID, a_volID, &volumeXInfo); - if (code) - fprintf(STDERR, - "[UV_XListOneVolume] Couldn't fetch the volume information\n"); - else - /* - * We got the info; pull out the pointer to where the results lie. - */ - *a_resultPP = volumeXInfo.volXEntries_val; - - /* - * If we got an Rx connection, throw it away. - */ - if (rxConnP) - rx_DestroyConnection(rxConnP); - - PrintError("", code); - return code; -} - -/* CheckVolume() - * Given a volume we read from a partition, check if it is - * represented in the VLDB correctly. - * - * The VLDB is looked up by the RW volume id (not its name). - * The RW contains the true name of the volume (BK and RO set - * the name in the VLDB only on creation of the VLDB entry). - * We want rules strict enough that when we check all volumes - * on one partition, it does not need to be done again. IE: - * two volumes on different partitions won't constantly - * change a VLDB entry away from what the other set. - * For RW and BK volumes, we will always check the VLDB to see - * if the two exist on the server/partition. May seem redundant, - * but this is an easy check of the VLDB. IE: if the VLDB entry - * says the BK exists but no BK volume is there, we will detect - * this when we check the RW volume. - * VLDB entries are locked only when a change needs to be done. - * Output changed to look a lot like the "vos syncserv" otuput. - */ -static afs_int32 -CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart, - afs_int32 * modentry, afs_uint32 * maxvolid) -{ - int idx, j; - afs_int32 code, error = 0; - struct nvldbentry entry, storeEntry; - char pname[10]; - int pass = 0, islocked = 0, createentry, addvolume, modified, mod; - afs_int32 rwvolid; - - if (modentry) - *modentry = 0; - rwvolid = - ((volumeinfo->type == - RWVOL) ? volumeinfo->volid : volumeinfo->parentID); - - retry: - /* Check to see if the VLDB is ok without locking it (pass 1). - * If it will change, then lock the VLDB entry, read it again, - * then make the changes to it (pass 2). - */ - if (++pass == 2) { - code = ubik_Call(VL_SetLock, cstruct, 0, rwvolid, RWVOL, VLOP_DELETE); - if (code) { - fprintf(STDERR, "Could not lock VLDB entry for %lu\n", - (unsigned long)rwvolid); - ERROR_EXIT(code); - } - islocked = 1; - } - - createentry = 0; /* Do we need to create a VLDB entry */ - addvolume = 0; /* Add this volume to the VLDB entry */ - modified = 0; /* The VLDB entry was modified */ - - /* Read the entry from VLDB by its RW volume id */ - code = VLDB_GetEntryByID(rwvolid, RWVOL, &entry); - if (code) { - if (code != VL_NOENT) { - fprintf(STDOUT, - "Could not retreive the VLDB entry for volume %lu \n", - (unsigned long)rwvolid); - ERROR_EXIT(code); - } - - memset(&entry, 0, sizeof(entry)); - vsu_ExtractName(entry.name, volumeinfo->name); /* Store name of RW */ - - createentry = 1; - } else { - MapHostToNetwork(&entry); - } - - if (verbose && (pass == 1)) { - fprintf(STDOUT, "_______________________________\n"); - fprintf(STDOUT, "\n-- status before -- \n"); - if (createentry) { - fprintf(STDOUT, "\n**does not exist**\n"); - } else { - if ((entry.flags & RW_EXISTS) || (entry.flags & RO_EXISTS) - || (entry.flags & BACK_EXISTS)) - EnumerateEntry(&entry); - } - fprintf(STDOUT, "\n"); - } - - if (volumeinfo->type == RWVOL) { /* RW volume exists */ - if (createentry) { - idx = 0; - entry.nServers = 1; - addvolume++; - } else { - /* Check existence of RW and BK volumes */ - code = CheckVldbRWBK(&entry, &mod); - if (code) - ERROR_EXIT(code); - if (mod) - modified++; - - idx = Lp_GetRwIndex(&entry); - if (idx == -1) { /* RW index not found in the VLDB entry */ - idx = entry.nServers; /* put it into next index */ - entry.nServers++; - addvolume++; - } else { /* RW index found in the VLDB entry. */ - /* Verify if this volume's location matches where the VLDB says it is */ - if (!Lp_Match(aserver, apart, &entry)) { - if (entry.flags & RW_EXISTS) { - /* The RW volume exists elsewhere - report this one a duplicate */ - if (pass == 1) { - MapPartIdIntoName(apart, pname); - fprintf(STDERR, - "*** Warning: Orphaned RW volume %lu exists on %s %s\n", - (unsigned long)rwvolid, - hostutil_GetNameByINet(aserver), pname); - MapPartIdIntoName(entry.serverPartition[idx], - pname); - fprintf(STDERR, - " VLDB reports RW volume %lu exists on %s %s\n", - (unsigned long)rwvolid, - hostutil_GetNameByINet(entry. - serverNumber[idx]), - pname); - } - } else { - /* The RW volume does not exist - have VLDB point to this one */ - addvolume++; - - /* Check for orphaned BK volume on old partition */ - if (entry.flags & BACK_EXISTS) { - if (pass == 1) { - MapPartIdIntoName(entry.serverPartition[idx], - pname); - fprintf(STDERR, - "*** Warning: Orphaned BK volume %u exists on %s %s\n", - entry.volumeId[BACKVOL], - hostutil_GetNameByINet(entry. - serverNumber - [idx]), pname); - MapPartIdIntoName(apart, pname); - fprintf(STDERR, - " VLDB reports its RW volume %lu exists on %s %s\n", - (unsigned long)rwvolid, - hostutil_GetNameByINet(aserver), - pname); - } - } - } - } else { - /* Volume location matches the VLDB location */ - if ((volumeinfo->backupID && !entry.volumeId[BACKVOL]) - || (volumeinfo->cloneID && !entry.volumeId[ROVOL]) - || - (strncmp - (entry.name, volumeinfo->name, - VOLSER_OLDMAXVOLNAME) != 0)) { - addvolume++; - } - } - } - } - - if (addvolume) { - entry.flags |= RW_EXISTS; - entry.volumeId[RWVOL] = rwvolid; - if (!entry.volumeId[BACKVOL]) - entry.volumeId[BACKVOL] = volumeinfo->backupID; - if (!entry.volumeId[ROVOL]) - entry.volumeId[ROVOL] = volumeinfo->cloneID; - - entry.serverFlags[idx] = ITSRWVOL; - entry.serverNumber[idx] = aserver; - entry.serverPartition[idx] = apart; - strncpy(entry.name, volumeinfo->name, VOLSER_OLDMAXVOLNAME); - - modified++; - - /* One last check - to update BK if need to */ - code = CheckVldbRWBK(&entry, &mod); - if (code) - ERROR_EXIT(code); - if (mod) - modified++; - } - } - - else if (volumeinfo->type == BACKVOL) { /* A BK volume */ - if (createentry) { - idx = 0; - entry.nServers = 1; - addvolume++; - } else { - /* Check existence of RW and BK volumes */ - code = CheckVldbRWBK(&entry, &mod); - if (code) - ERROR_EXIT(code); - if (mod) - modified++; - - idx = Lp_GetRwIndex(&entry); - if (idx == -1) { /* RW index not found in the VLDB entry */ - idx = entry.nServers; /* Put it into next index */ - entry.nServers++; - addvolume++; - } else { /* RW index found in the VLDB entry */ - /* Verify if this volume's location matches where the VLDB says it is */ - if (!Lp_Match(aserver, apart, &entry)) { - /* VLDB says RW and/or BK is elsewhere - report this BK volume orphaned */ - if (pass == 1) { - MapPartIdIntoName(apart, pname); - fprintf(STDERR, - "*** Warning: Orphaned BK volume %lu exists on %s %s\n", - (unsigned long)volumeinfo->volid, - hostutil_GetNameByINet(aserver), pname); - MapPartIdIntoName(entry.serverPartition[idx], pname); - fprintf(STDERR, - " VLDB reports its RW/BK volume %lu exists on %s %s\n", - (unsigned long)rwvolid, - hostutil_GetNameByINet(entry. - serverNumber[idx]), - pname); - } - } else { - if (volumeinfo->volid != entry.volumeId[BACKVOL]) { - if (!(entry.flags & BACK_EXISTS)) { - addvolume++; - } else if (volumeinfo->volid > - entry.volumeId[BACKVOL]) { - addvolume++; - - if (pass == 1) { - MapPartIdIntoName(entry.serverPartition[idx], - pname); - fprintf(STDERR, - "*** Warning: Orphaned BK volume %u exists on %s %s\n", - entry.volumeId[BACKVOL], - hostutil_GetNameByINet(aserver), - pname); - fprintf(STDERR, - " VLDB reports its BK volume ID is %lu\n", - (unsigned long)volumeinfo->volid); - } - } else { - if (pass == 1) { - MapPartIdIntoName(entry.serverPartition[idx], - pname); - fprintf(STDERR, - "*** Warning: Orphaned BK volume %lu exists on %s %s\n", - (unsigned long)volumeinfo->volid, - hostutil_GetNameByINet(aserver), - pname); - fprintf(STDERR, - " VLDB reports its BK volume ID is %u\n", - entry.volumeId[BACKVOL]); - } - } - } else if (!entry.volumeId[BACKVOL]) { - addvolume++; - } - } - } - } - if (addvolume) { - entry.flags |= BACK_EXISTS; - entry.volumeId[RWVOL] = rwvolid; - entry.volumeId[BACKVOL] = volumeinfo->volid; - - entry.serverNumber[idx] = aserver; - entry.serverPartition[idx] = apart; - entry.serverFlags[idx] = ITSRWVOL; - - modified++; - } - } - - else if (volumeinfo->type == ROVOL) { /* A RO volume */ - if (volumeinfo->volid == entry.volumeId[ROVOL]) { - /* This is a quick check to see if the RO entry exists in the - * VLDB so we avoid the CheckVldbRO() call (which checks if each - * RO volume listed in the VLDB exists). - */ - idx = Lp_ROMatch(aserver, apart, &entry) - 1; - if (idx == -1) { - idx = entry.nServers; - entry.nServers++; - addvolume++; - } else { - if (!(entry.flags & RO_EXISTS)) { - addvolume++; - } - } - } else { - /* Before we correct the VLDB entry, make sure all the - * ROs listed in the VLDB exist. - */ - code = CheckVldbRO(&entry, &mod); - if (code) - ERROR_EXIT(code); - if (mod) - modified++; - - if (!(entry.flags & RO_EXISTS)) { - /* No RO exists in the VLDB entry - add this one */ - idx = entry.nServers; - entry.nServers++; - addvolume++; - } else if (volumeinfo->volid > entry.volumeId[ROVOL]) { - /* The volume headers's RO ID does not match that in the VLDB entry, - * and the vol hdr's ID is greater (implies more recent). So delete - * all the RO volumes listed in VLDB entry and add this volume. - */ - for (j = 0; j < entry.nServers; j++) { - if (entry.serverFlags[j] & ITSROVOL) { - /* Verify this volume exists and print message we are orphaning it */ - if (pass == 1) { - MapPartIdIntoName(apart, pname); - fprintf(STDERR, - "*** Warning: Orphaned RO volume %u exists on %s %s\n", - entry.volumeId[ROVOL], - hostutil_GetNameByINet(entry. - serverNumber[j]), - pname); - fprintf(STDERR, - " VLDB reports its RO volume ID is %lu\n", - (unsigned long)volumeinfo->volid); - } - - Lp_SetRWValue(entry, entry.serverNumber[idx], - entry.serverPartition[idx], 0L, 0L); - entry.nServers--; - modified++; - j--; - } - } - - idx = entry.nServers; - entry.nServers++; - addvolume++; - } else if (volumeinfo->volid < entry.volumeId[ROVOL]) { - /* The volume headers's RO ID does not match that in the VLDB entry, - * and the vol hdr's ID is lower (implies its older). So orphan it. - */ - if (pass == 1) { - MapPartIdIntoName(apart, pname); - fprintf(STDERR, - "*** Warning: Orphaned RO volume %lu exists on %s %s\n", - (unsigned long)volumeinfo->volid, - hostutil_GetNameByINet(aserver), pname); - fprintf(STDERR, - " VLDB reports its RO volume ID is %u\n", - entry.volumeId[ROVOL]); - } - } else { - /* The RO volume ID in the volume header match that in the VLDB entry, - * and there exist RO volumes in the VLDB entry. See if any of them - * are this one. If not, then we add it. - */ - idx = Lp_ROMatch(aserver, apart, &entry) - 1; - if (idx == -1) { - idx = entry.nServers; - entry.nServers++; - addvolume++; - } - } - } - - if (addvolume) { - entry.flags |= RO_EXISTS; - entry.volumeId[RWVOL] = rwvolid; - entry.volumeId[ROVOL] = volumeinfo->volid; - - entry.serverNumber[idx] = aserver; - entry.serverPartition[idx] = apart; - entry.serverFlags[idx] = ITSROVOL; - - modified++; - } - } - - /* Remember largest volume id */ - if (entry.volumeId[ROVOL] > *maxvolid) - *maxvolid = entry.volumeId[ROVOL]; - if (entry.volumeId[BACKVOL] > *maxvolid) - *maxvolid = entry.volumeId[BACKVOL]; - if (entry.volumeId[RWVOL] > *maxvolid) - *maxvolid = entry.volumeId[RWVOL]; - - if (modified) { - MapNetworkToHost(&entry, &storeEntry); - - if (createentry) { - code = VLDB_CreateEntry(&storeEntry); - if (code) { - fprintf(STDOUT, - "Could not create a VLDB entry for the volume %lu\n", - (unsigned long)rwvolid); - ERROR_EXIT(code); - } - } else { - if (pass == 1) - goto retry; - code = - VLDB_ReplaceEntry(rwvolid, RWVOL, &storeEntry, - LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP); - if (code) { - fprintf(STDERR, "Could not update entry for %lu\n", - (unsigned long)rwvolid); - ERROR_EXIT(code); - } - } - if (modentry) - *modentry = modified; - } else if (pass == 2) { - code = - ubik_Call(VL_ReleaseLock, cstruct, 0, rwvolid, RWVOL, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (code) { - PrintError("Could not unlock VLDB entry ", code); - } - } - - if (verbose) { - fprintf(STDOUT, "-- status after --\n"); - if (modified) - EnumerateEntry(&entry); - else - fprintf(STDOUT, "\n**no change**\n"); - } - - error_exit: - VPRINT("\n_______________________________\n"); - return (error); -} - -int -sortVolumes(const void *a, const void *b) -{ - volintInfo *v1 = (volintInfo *) a; - volintInfo *v2 = (volintInfo *) b; - afs_int32 rwvolid1, rwvolid2; - - rwvolid1 = ((v1->type == RWVOL) ? v1->volid : v1->parentID); - rwvolid2 = ((v2->type == RWVOL) ? v2->volid : v2->parentID); - - if (rwvolid1 > rwvolid2) - return -1; /* lower RW id goes first */ - if (rwvolid1 < rwvolid2) - return 1; - - if (v1->type == RWVOL) - return -1; /* RW vols go first */ - if (v2->type == RWVOL) - return 1; - - if ((v1->type == BACKVOL) && (v2->type == ROVOL)) - return -1; /* BK vols next */ - if ((v1->type == ROVOL) && (v2->type == BACKVOL)) - return 1; - - if (v1->volid < v2->volid) - return 1; /* larger volids first */ - if (v1->volid > v2->volid) - return -1; - return 0; -} - -/* UV_SyncVolume() - * Synchronise (if flags = 1) . - * Synchronize an individual volume against a sever and partition. - * Checks the VLDB entry (similar to syncserv) as well as checks - * if the volume exists on specified servers (similar to syncvldb). - */ -int -UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags) -{ - struct rx_connection *aconn = 0; - afs_int32 j, k, code, vcode, error = 0; - afs_int32 tverbose, mod, modified = 0; - struct nvldbentry vldbentry; - afs_int32 volumeid = 0; - volEntries volumeInfo; - struct partList PartList; - afs_int32 pcnt, rv; - afs_int32 maxvolid = 0; - - volumeInfo.volEntries_val = (volintInfo *) 0; - volumeInfo.volEntries_len = 0; - - if (!aserver && flags) { - /* fprintf(STDERR,"Partition option requires a server option\n"); */ - ERROR_EXIT(EINVAL); - } - - /* Turn verbose logging off and do our own verbose logging */ - tverbose = verbose; - verbose = 0; - - /* Read the VLDB entry */ - vcode = VLDB_GetEntryByName(avolname, &vldbentry); - if (vcode && (vcode != VL_NOENT)) { - fprintf(STDERR, "Could not access the VLDB for volume %s\n", - avolname); - ERROR_EXIT(vcode); - } else if (!vcode) { - MapHostToNetwork(&vldbentry); - } - - if (tverbose) { - fprintf(STDOUT, "Processing VLDB entry %s ...\n", avolname); - fprintf(STDOUT, "_______________________________\n"); - fprintf(STDOUT, "\n-- status before -- \n"); - if (vcode) { - fprintf(STDOUT, "\n**does not exist**\n"); - } else { - if ((vldbentry.flags & RW_EXISTS) || (vldbentry.flags & RO_EXISTS) - || (vldbentry.flags & BACK_EXISTS)) - EnumerateEntry(&vldbentry); - } - fprintf(STDOUT, "\n"); - } - - /* Verify that all of the VLDB entries exist on the repective servers - * and partitions (this does not require that avolname be a volume ID). - * Equivalent to a syncserv. - */ - if (!vcode) { - code = CheckVldb(&vldbentry, &mod); - if (code) { - fprintf(STDERR, "Could not process VLDB entry for volume %s\n", - vldbentry.name); - ERROR_EXIT(code); - } - if (mod) - modified++; - } - - /* If aserver is given, we will search for the desired volume on it */ - if (aserver) { - /* Generate array of partitions on the server that we will check */ - if (!flags) { - code = UV_ListPartitions(aserver, &PartList, &pcnt); - if (code) { - fprintf(STDERR, - "Could not fetch the list of partitions from the server\n"); - ERROR_EXIT(code); - } - } else { - PartList.partId[0] = apart; - pcnt = 1; - } - - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - - /* If a volume ID were given, search for it on each partition */ - if ((volumeid = atol(avolname))) { - for (j = 0; j < pcnt; j++) { - code = - AFSVolListOneVolume(aconn, PartList.partId[j], volumeid, - &volumeInfo); - if (code) { - if (code != ENODEV) { - fprintf(STDERR, "Could not query server\n"); - ERROR_EXIT(code); - } - } else { - /* Found one, sync it with VLDB entry */ - code = - CheckVolume(volumeInfo.volEntries_val, aserver, - PartList.partId[j], &mod, &maxvolid); - if (code) - ERROR_EXIT(code); - if (mod) - modified++; - } - - if (volumeInfo.volEntries_val) - free(volumeInfo.volEntries_val); - volumeInfo.volEntries_val = (volintInfo *) 0; - volumeInfo.volEntries_len = 0; - } - } - - /* Check to see if the RW, BK, and RO IDs exist on any - * partitions. We get the volume IDs from the VLDB. - */ - rv = 1; /* Read the VLDB entry ? */ - for (j = 0; j < MAXTYPES; j++) { /* for RW, RO, and BK IDs */ - if (rv) { - vcode = VLDB_GetEntryByName(avolname, &vldbentry); - if (vcode) { - if (vcode == VL_NOENT) - break; - fprintf(STDERR, - "Could not access the VLDB for volume %s\n", - avolname); - ERROR_EXIT(vcode); - } - rv = 0; - } - - if (vldbentry.volumeId[j] == 0) - continue; - - for (k = 0; k < pcnt; k++) { /* For each partition */ - volumeInfo.volEntries_val = (volintInfo *) 0; - volumeInfo.volEntries_len = 0; - code = - AFSVolListOneVolume(aconn, PartList.partId[k], - vldbentry.volumeId[j], &volumeInfo); - if (code) { - if (code != ENODEV) { - fprintf(STDERR, "Could not query server\n"); - ERROR_EXIT(code); - } - } else { - /* Found one, sync it with VLDB entry */ - code = - CheckVolume(volumeInfo.volEntries_val, aserver, - PartList.partId[k], &mod, &maxvolid); - if (code) - ERROR_EXIT(code); - if (mod) - modified++, rv++; - } - - if (volumeInfo.volEntries_val) - free(volumeInfo.volEntries_val); - volumeInfo.volEntries_val = (volintInfo *) 0; - volumeInfo.volEntries_len = 0; - } - } - } - - /* if (aserver) */ - /* If verbose output, print a summary of what changed */ - if (tverbose) { - fprintf(STDOUT, "-- status after --\n"); - code = VLDB_GetEntryByName(avolname, &vldbentry); - if (code && (code != VL_NOENT)) { - fprintf(STDERR, "Could not access the VLDB for volume %s\n", - avolname); - ERROR_EXIT(code); - } - if (modified && (code == VL_NOENT)) { - fprintf(STDOUT, "\n**entry deleted**\n"); - } else if (modified) { - EnumerateEntry(&vldbentry); - } else { - fprintf(STDOUT, "\n**no change**\n"); - } - fprintf(STDOUT, "\n_______________________________\n"); - } - - error_exit: - /* Now check if the maxvolid is larger than that stored in the VLDB */ - if (maxvolid) { - afs_int32 maxvldbid = 0; - code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 0, &maxvldbid); - if (code) { - fprintf(STDERR, - "Could not get the highest allocated volume id from the VLDB\n"); - if (!error) - error = code; - } else if (maxvolid > maxvldbid) { - afs_uint32 id, nid; - id = maxvolid - maxvldbid + 1; - code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &nid); - if (code) { - fprintf(STDERR, - "Error in increasing highest allocated volume id in VLDB\n"); - if (!error) - error = code; - } - } - } - - verbose = tverbose; - if (verbose) { - if (error) - fprintf(STDOUT, "...error encountered"); - else - fprintf(STDOUT, "...done entry\n"); - } - if (aconn) - rx_DestroyConnection(aconn); - if (volumeInfo.volEntries_val) - free(volumeInfo.volEntries_val); - - PrintError("", error); - return error; -} - -/* UV_SyncVldb() - * Synchronise vldb with the file server and, - * optionally, . - */ -int -UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force) -{ - struct rx_connection *aconn; - afs_int32 code, error = 0; - int i, j, pfail; - volEntries volumeInfo; - struct partList PartList; - afs_int32 pcnt; - char pname[10]; - volintInfo *vi; - afs_int32 failures = 0, modifications = 0, tentries = 0; - afs_int32 modified; - afs_uint32 maxvolid = 0; - - volumeInfo.volEntries_val = (volintInfo *) 0; - volumeInfo.volEntries_len = 0; - - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - - /* Generate array of partitions to check */ - if (!flags) { - code = UV_ListPartitions(aserver, &PartList, &pcnt); - if (code) { - fprintf(STDERR, - "Could not fetch the list of partitions from the server\n"); - ERROR_EXIT(code); - } - } else { - PartList.partId[0] = apart; - pcnt = 1; - } - - VPRINT("Processing volume entries ...\n"); - - /* Step through the array of partitions */ - for (i = 0; i < pcnt; i++) { - apart = PartList.partId[i]; - MapPartIdIntoName(apart, pname); - - volumeInfo.volEntries_val = (volintInfo *) 0; - volumeInfo.volEntries_len = 0; - code = AFSVolListVolumes(aconn, apart, 1, &volumeInfo); - if (code) { - fprintf(STDERR, - "Could not fetch the list of volumes from the server\n"); - ERROR_EXIT(code); - } - - /* May want to sort the entries: RW, BK (high to low), RO (high to low) */ - qsort((char *)volumeInfo.volEntries_val, volumeInfo.volEntries_len, - sizeof(volintInfo), sortVolumes); - - pfail = 0; - for (vi = volumeInfo.volEntries_val, j = 0; - j < volumeInfo.volEntries_len; j++, vi++) { - if (!vi->status) - continue; - - tentries++; - - if (verbose) { - fprintf(STDOUT, - "Processing volume entry %d: %s (%lu) on server %s %s...\n", - j + 1, vi->name, (unsigned long)vi->volid, - hostutil_GetNameByINet(aserver), pname); - fflush(STDOUT); - } - - code = CheckVolume(vi, aserver, apart, &modified, &maxvolid); - if (code) { - PrintError("", code); - failures++; - pfail++; - } else if (modified) { - modifications++; - } - - if (verbose) { - if (code) { - fprintf(STDOUT, "...error encountered\n\n"); - } else { - fprintf(STDOUT, "...done entry %d\n\n", j + 1); - } - } - } - - if (pfail) { - fprintf(STDERR, - "Could not process entries on server %s partition %s\n", - hostutil_GetNameByINet(aserver), pname); - } - if (volumeInfo.volEntries_val) { - free(volumeInfo.volEntries_val); - volumeInfo.volEntries_val = 0; - } - - } /* thru all partitions */ - - VPRINT3("Total entries: %u, Failed to process %d, Changed %d\n", tentries, - failures, modifications); - - error_exit: - /* Now check if the maxvolid is larger than that stored in the VLDB */ - if (maxvolid) { - afs_uint32 maxvldbid = 0; - code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 0, &maxvldbid); - if (code) { - fprintf(STDERR, - "Could not get the highest allocated volume id from the VLDB\n"); - if (!error) - error = code; - } else if (maxvolid > maxvldbid) { - afs_uint32 id, nid; - id = maxvolid - maxvldbid + 1; - code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &nid); - if (code) { - fprintf(STDERR, - "Error in increasing highest allocated volume id in VLDB\n"); - if (!error) - error = code; - } - } - } - - if (aconn) - rx_DestroyConnection(aconn); - if (volumeInfo.volEntries_val) - free(volumeInfo.volEntries_val); - PrintError("", error); - return (error); -} - -/* VolumeExists() - * Determine if a volume exists on a server and partition. - * Try creating a transaction on the volume. If we can, - * the volume exists, if not, then return the error code. - * Some error codes mean the volume is unavailable but - * still exists - so we catch these error codes. - */ -afs_int32 -VolumeExists(afs_int32 server, afs_int32 partition, afs_int32 volumeid) -{ - struct rx_connection *conn = (struct rx_connection *)0; - afs_int32 code = -1; - volEntries volumeInfo; - - conn = UV_Bind(server, AFSCONF_VOLUMEPORT); - if (conn) { - volumeInfo.volEntries_val = (volintInfo *) 0; - volumeInfo.volEntries_len = 0; - code = AFSVolListOneVolume(conn, partition, volumeid, &volumeInfo); - if (volumeInfo.volEntries_val) - free(volumeInfo.volEntries_val); - if (code == VOLSERILLEGAL_PARTITION) - code = ENODEV; - rx_DestroyConnection(conn); - } - return code; -} - -/* CheckVldbRWBK() - * - */ -afs_int32 -CheckVldbRWBK(struct nvldbentry * entry, afs_int32 * modified) -{ - int modentry = 0; - int idx; - afs_int32 code, error = 0; - char pname[10]; - - if (modified) - *modified = 0; - idx = Lp_GetRwIndex(entry); - - /* Check to see if the RW volume exists and set the RW_EXISTS - * flag accordingly. - */ - if (idx == -1) { /* Did not find a RW entry */ - if (entry->flags & RW_EXISTS) { /* ... yet entry says RW exists */ - entry->flags &= ~RW_EXISTS; /* ... so say RW does not exist */ - modentry++; - } - } else { - code = - VolumeExists(entry->serverNumber[idx], - entry->serverPartition[idx], entry->volumeId[RWVOL]); - if (code == 0) { /* RW volume exists */ - if (!(entry->flags & RW_EXISTS)) { /* ... yet entry says RW does not exist */ - entry->flags |= RW_EXISTS; /* ... so say RW does exist */ - modentry++; - } - } else if (code == ENODEV) { /* RW volume does not exist */ - if (entry->flags & RW_EXISTS) { /* ... yet entry says RW exists */ - entry->flags &= ~RW_EXISTS; /* ... so say RW does not exist */ - modentry++; - } - } else { - /* If VLDB says it didn't exist, then ignore error */ - if (entry->flags & RW_EXISTS) { - MapPartIdIntoName(entry->serverPartition[idx], pname); - fprintf(STDERR, - "Transaction call failed for RW volume %u on server %s %s\n", - entry->volumeId[RWVOL], - hostutil_GetNameByINet(entry->serverNumber[idx]), - pname); - ERROR_EXIT(code); - } - } - } - - /* Check to see if the BK volume exists and set the BACK_EXISTS - * flag accordingly. idx already ponts to the RW entry. - */ - if (idx == -1) { /* Did not find a RW entry */ - if (entry->flags & BACK_EXISTS) { /* ... yet entry says BK exists */ - entry->flags &= ~BACK_EXISTS; /* ... so say BK does not exist */ - modentry++; - } - } else { /* Found a RW entry */ - code = - VolumeExists(entry->serverNumber[idx], - entry->serverPartition[idx], - entry->volumeId[BACKVOL]); - if (code == 0) { /* BK volume exists */ - if (!(entry->flags & BACK_EXISTS)) { /* ... yet entry says BK does not exist */ - entry->flags |= BACK_EXISTS; /* ... so say BK does exist */ - modentry++; - } - } else if (code == ENODEV) { /* BK volume does not exist */ - if (entry->flags & BACK_EXISTS) { /* ... yet entry says BK exists */ - entry->flags &= ~BACK_EXISTS; /* ... so say BK does not exist */ - modentry++; - } - } else { - /* If VLDB says it didn't exist, then ignore error */ - if (entry->flags & BACK_EXISTS) { - MapPartIdIntoName(entry->serverPartition[idx], pname); - fprintf(STDERR, - "Transaction call failed for BK volume %u on server %s %s\n", - entry->volumeId[BACKVOL], - hostutil_GetNameByINet(entry->serverNumber[idx]), - pname); - ERROR_EXIT(code); - } - } - } - - /* If there is an idx but the BK and RW volumes no - * longer exist, then remove the RW entry. - */ - if ((idx != -1) && !(entry->flags & RW_EXISTS) - && !(entry->flags & BACK_EXISTS)) { - Lp_SetRWValue(entry, entry->serverNumber[idx], - entry->serverPartition[idx], 0L, 0L); - entry->nServers--; - modentry++; - } - - error_exit: - if (modified) - *modified = modentry; - return (error); -} - -int -CheckVldbRO(struct nvldbentry *entry, afs_int32 * modified) -{ - int idx; - int foundro = 0, modentry = 0; - afs_int32 code, error = 0; - char pname[10]; - - if (modified) - *modified = 0; - - /* Check to see if the RO volumes exist and set the RO_EXISTS - * flag accordingly. - */ - for (idx = 0; idx < entry->nServers; idx++) { - if (!(entry->serverFlags[idx] & ITSROVOL)) { - continue; /* not a RO */ - } - - code = - VolumeExists(entry->serverNumber[idx], - entry->serverPartition[idx], entry->volumeId[ROVOL]); - if (code == 0) { /* RO volume exists */ - foundro++; - } else if (code == ENODEV) { /* RW volume does not exist */ - Lp_SetROValue(entry, entry->serverNumber[idx], - entry->serverPartition[idx], 0L, 0L); - entry->nServers--; - idx--; - modentry++; - } else { - MapPartIdIntoName(entry->serverPartition[idx], pname); - fprintf(STDERR, - "Transaction call failed for RO %u on server %s %s\n", - entry->volumeId[ROVOL], - hostutil_GetNameByINet(entry->serverNumber[idx]), pname); - ERROR_EXIT(code); - } - } - - if (foundro) { /* A RO volume exists */ - if (!(entry->flags & RO_EXISTS)) { /* ... yet entry says RW does not exist */ - entry->flags |= RO_EXISTS; /* ... so say RW does exist */ - modentry++; - } - } else { /* A RO volume does not exist */ - if (entry->flags & RO_EXISTS) { /* ... yet entry says RO exists */ - entry->flags &= ~RO_EXISTS; /* ... so say RO does not exist */ - modentry++; - } - } - - error_exit: - if (modified) - *modified = modentry; - return (error); -} - -/* CheckVldb() - * Ensure that matches with the info on file servers - */ -afs_int32 -CheckVldb(struct nvldbentry * entry, afs_int32 * modified) -{ - afs_int32 code, error = 0; - struct nvldbentry storeEntry; - int islocked = 0, mod, modentry, delentry = 0; - int pass = 0; - - if (modified) - *modified = 0; - if (verbose) { - fprintf(STDOUT, "_______________________________\n"); - fprintf(STDOUT, "\n-- status before -- \n"); - if ((entry->flags & RW_EXISTS) || (entry->flags & RO_EXISTS) - || (entry->flags & BACK_EXISTS)) - EnumerateEntry(entry); - fprintf(STDOUT, "\n"); - } - - if (strlen(entry->name) > (VOLSER_OLDMAXVOLNAME - 10)) { - fprintf(STDERR, "Volume name %s exceeds limit of %d characters\n", - entry->name, VOLSER_OLDMAXVOLNAME - 10); - } - - retry: - /* Check to see if the VLDB is ok without locking it (pass 1). - * If it will change, then lock the VLDB entry, read it again, - * then make the changes to it (pass 2). - */ - if (++pass == 2) { - code = - ubik_Call(VL_SetLock, cstruct, 0, entry->volumeId[RWVOL], RWVOL, - VLOP_DELETE); - if (code) { - fprintf(STDERR, "Could not lock VLDB entry for %u \n", - entry->volumeId[RWVOL]); - ERROR_EXIT(code); - } - islocked = 1; - - code = VLDB_GetEntryByID(entry->volumeId[RWVOL], RWVOL, entry); - if (code) { - fprintf(STDERR, "Could not read VLDB entry for volume %s\n", - entry->name); - ERROR_EXIT(code); - } else { - MapHostToNetwork(entry); - } - } - - modentry = 0; - - /* Check if the RW and BK entries are ok */ - code = CheckVldbRWBK(entry, &mod); - if (code) - ERROR_EXIT(code); - if (mod && (pass == 1)) - goto retry; - if (mod) - modentry++; - - /* Check if the RO volumes entries are ok */ - code = CheckVldbRO(entry, &mod); - if (code) - ERROR_EXIT(code); - if (mod && (pass == 1)) - goto retry; - if (mod) - modentry++; - - /* The VLDB entry has been updated. If it as been modified, then - * write the entry back out the the VLDB. - */ - if (modentry) { - if (pass == 1) - goto retry; - - if (!(entry->flags & RW_EXISTS) && !(entry->flags & BACK_EXISTS) - && !(entry->flags & RO_EXISTS)) { - /* The RW, BK, nor RO volumes do not exist. Delete the VLDB entry */ - code = - ubik_Call(VL_DeleteEntry, cstruct, 0, entry->volumeId[RWVOL], - RWVOL); - if (code) { - fprintf(STDERR, - "Could not delete VLDB entry for volume %u \n", - entry->volumeId[RWVOL]); - ERROR_EXIT(code); - } - delentry = 1; - } else { - /* Replace old entry with our new one */ - MapNetworkToHost(entry, &storeEntry); - code = - VLDB_ReplaceEntry(entry->volumeId[RWVOL], RWVOL, &storeEntry, - (LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP)); - if (code) { - fprintf(STDERR, "Could not update VLDB entry for volume %u\n", - entry->volumeId[RWVOL]); - ERROR_EXIT(code); - } - } - if (modified) - *modified = 1; - islocked = 0; - } - - if (verbose) { - fprintf(STDOUT, "-- status after --\n"); - if (delentry) - fprintf(STDOUT, "\n**entry deleted**\n"); - else if (modentry) - EnumerateEntry(entry); - else - fprintf(STDOUT, "\n**no change**\n"); - } - - error_exit: - VPRINT("\n_______________________________\n"); - - if (islocked) { - code = - ubik_Call(VL_ReleaseLock, cstruct, 0, entry->volumeId[RWVOL], - RWVOL, - (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP)); - if (code) { - fprintf(STDERR, - "Could not release lock on VLDB entry for volume %u\n", - entry->volumeId[RWVOL]); - if (!error) - error = code; - } - } - return error; -} - -/* UV_SyncServer() - * Synchronise (if flags = 1) with the VLDB. - */ -int -UV_SyncServer(afs_int32 aserver, afs_int32 apart, int flags, int force) -{ - struct rx_connection *aconn; - afs_int32 code, error = 0; - afs_int32 nentries, tentries = 0; - struct VldbListByAttributes attributes; - nbulkentries arrayEntries; - afs_int32 failures = 0, modified, modifications = 0; - struct nvldbentry *vlentry; - afs_int32 si, nsi, j; - - aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT); - - /* Set up attributes to search VLDB */ - attributes.server = ntohl(aserver); - attributes.Mask = VLLIST_SERVER; - if (flags) { - attributes.partition = apart; - attributes.Mask |= VLLIST_PARTITION; - } - - VPRINT("Processing VLDB entries ...\n"); - - /* While we need to collect more VLDB entries */ - for (si = 0; si != -1; si = nsi) { - memset(&arrayEntries, 0, sizeof(arrayEntries)); - - /* Collect set of VLDB entries */ - code = - VLDB_ListAttributesN2(&attributes, 0, si, &nentries, - &arrayEntries, &nsi); - if (code == RXGEN_OPCODE) { - code = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries); - nsi = -1; - } - if (code) { - fprintf(STDERR, "Could not access the VLDB for attributes\n"); - ERROR_EXIT(code); - } - tentries += nentries; - - for (j = 0; j < nentries; j++) { - vlentry = &arrayEntries.nbulkentries_val[j]; - MapHostToNetwork(vlentry); - - VPRINT1("Processing VLDB entry %d ...\n", j + 1); - - code = CheckVldb(vlentry, &modified); - if (code) { - PrintError("", code); - fprintf(STDERR, - "Could not process VLDB entry for volume %s\n", - vlentry->name); - failures++; - } else if (modified) { - modifications++; - } - - if (verbose) { - if (code) { - fprintf(STDOUT, "...error encountered\n\n"); - } else { - fprintf(STDOUT, "...done entry %d\n\n", j + 1); - } - } - } - - if (arrayEntries.nbulkentries_val) { - free(arrayEntries.nbulkentries_val); - arrayEntries.nbulkentries_val = 0; - } - } - - VPRINT3("Total entries: %u, Failed to process %d, Changed %d\n", tentries, - failures, modifications); - - error_exit: - if (aconn) - rx_DestroyConnection(aconn); - if (arrayEntries.nbulkentries_val) - free(arrayEntries.nbulkentries_val); - - if (failures) - error = VOLSERFAILEDOP; - return error; -} - -/*rename volume to , changing the names of the related - *readonly and backup volumes. This operation is also idempotent. - *salvager is capable of recovering from rename operation stopping halfway. - *to recover run syncserver on the affected machines,it will force renaming to completion. name clashes should have been detected before calling this proc */ -int -UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[]) -{ - struct nvldbentry storeEntry; - afs_int32 vcode, code, rcode, error; - int i, index; - char nameBuffer[256]; - afs_int32 tid; - struct rx_connection *aconn; - int islocked; - - error = 0; - aconn = (struct rx_connection *)0; - tid = 0; - islocked = 0; - - vcode = ubik_Call(VL_SetLock, cstruct, 0, entry->volumeId[RWVOL], RWVOL, VLOP_ADDSITE); /*last param is dummy */ - if (vcode) { - fprintf(STDERR, - " Could not lock the VLDB entry for the volume %u \n", - entry->volumeId[RWVOL]); - error = vcode; - goto rvfail; - } - islocked = 1; - strncpy(entry->name, newname, VOLSER_OLDMAXVOLNAME); - MapNetworkToHost(entry, &storeEntry); - vcode = VLDB_ReplaceEntry(entry->volumeId[RWVOL], RWVOL, &storeEntry, 0); - if (vcode) { - fprintf(STDERR, "Could not update VLDB entry for %u\n", - entry->volumeId[RWVOL]); - error = vcode; - goto rvfail; - } - VPRINT1("Recorded the new name %s in VLDB\n", newname); - /*at this stage the intent to rename is recorded in the vldb, as far as the vldb - * is concerned, oldname is lost */ - if (entry->flags & RW_EXISTS) { - index = Lp_GetRwIndex(entry); - if (index == -1) { /* there is a serious discrepancy */ - fprintf(STDERR, - "There is a serious discrepancy in VLDB entry for volume %u\n", - entry->volumeId[RWVOL]); - fprintf(STDERR, "try building VLDB from scratch\n"); - error = VOLSERVLDB_ERROR; - goto rvfail; - } - aconn = UV_Bind(entry->serverNumber[index], AFSCONF_VOLUMEPORT); - code = - AFSVolTransCreate(aconn, entry->volumeId[RWVOL], - entry->serverPartition[index], ITOffline, &tid); - if (code) { /*volume doesnot exist */ - fprintf(STDERR, - "Could not start transaction on the rw volume %u\n", - entry->volumeId[RWVOL]); - error = code; - goto rvfail; - } else { /*volume exists, process it */ - - code = - AFSVolSetIdsTypes(aconn, tid, newname, RWVOL, - entry->volumeId[RWVOL], - entry->volumeId[ROVOL], - entry->volumeId[BACKVOL]); - if (!code) { - VPRINT2("Renamed rw volume %s to %s\n", oldname, newname); - code = AFSVolEndTrans(aconn, tid, &rcode); - tid = 0; - if (code) { - fprintf(STDERR, - "Could not end transaction on volume %s %u\n", - entry->name, entry->volumeId[RWVOL]); - error = code; - goto rvfail; - } - } else { - fprintf(STDERR, "Could not set parameters on volume %s %u\n", - entry->name, entry->volumeId[RWVOL]); - error = code; - goto rvfail; - } - } - if (aconn) - rx_DestroyConnection(aconn); - aconn = (struct rx_connection *)0; - } - /*end rw volume processing */ - if (entry->flags & BACK_EXISTS) { /*process the backup volume */ - index = Lp_GetRwIndex(entry); - if (index == -1) { /* there is a serious discrepancy */ - fprintf(STDERR, - "There is a serious discrepancy in the VLDB entry for the backup volume %u\n", - entry->volumeId[BACKVOL]); - fprintf(STDERR, "try building VLDB from scratch\n"); - error = VOLSERVLDB_ERROR; - goto rvfail; - } - aconn = UV_Bind(entry->serverNumber[index], AFSCONF_VOLUMEPORT); - code = - AFSVolTransCreate(aconn, entry->volumeId[BACKVOL], - entry->serverPartition[index], ITOffline, &tid); - if (code) { /*volume doesnot exist */ - fprintf(STDERR, - "Could not start transaction on the backup volume %u\n", - entry->volumeId[BACKVOL]); - error = code; - goto rvfail; - } else { /*volume exists, process it */ - if (strlen(newname) > (VOLSER_OLDMAXVOLNAME - 8)) { - fprintf(STDERR, - "Volume name %s.backup exceeds the limit of %u characters\n", - newname, VOLSER_OLDMAXVOLNAME); - error = code; - goto rvfail; - } - strcpy(nameBuffer, newname); - strcat(nameBuffer, ".backup"); - - code = - AFSVolSetIdsTypes(aconn, tid, nameBuffer, BACKVOL, - entry->volumeId[RWVOL], 0, 0); - if (!code) { - VPRINT1("Renamed backup volume to %s \n", nameBuffer); - code = AFSVolEndTrans(aconn, tid, &rcode); - tid = 0; - if (code) { - fprintf(STDERR, - "Could not end transaction on the backup volume %u\n", - entry->volumeId[BACKVOL]); - error = code; - goto rvfail; - } - } else { - fprintf(STDERR, - "Could not set parameters on the backup volume %u\n", - entry->volumeId[BACKVOL]); - error = code; - goto rvfail; - } - } - } /* end backup processing */ - if (aconn) - rx_DestroyConnection(aconn); - aconn = (struct rx_connection *)0; - if (entry->flags & RO_EXISTS) { /*process the ro volumes */ - for (i = 0; i < entry->nServers; i++) { - if (entry->serverFlags[i] & ITSROVOL) { - aconn = UV_Bind(entry->serverNumber[i], AFSCONF_VOLUMEPORT); - code = - AFSVolTransCreate(aconn, entry->volumeId[ROVOL], - entry->serverPartition[i], ITOffline, - &tid); - if (code) { /*volume doesnot exist */ - fprintf(STDERR, - "Could not start transaction on the ro volume %u\n", - entry->volumeId[ROVOL]); - error = code; - goto rvfail; - } else { /*volume exists, process it */ - strcpy(nameBuffer, newname); - strcat(nameBuffer, ".readonly"); - if (strlen(nameBuffer) > (VOLSER_OLDMAXVOLNAME - 1)) { - fprintf(STDERR, - "Volume name %s exceeds the limit of %u characters\n", - nameBuffer, VOLSER_OLDMAXVOLNAME); - error = code; - goto rvfail; - } - code = - AFSVolSetIdsTypes(aconn, tid, nameBuffer, ROVOL, - entry->volumeId[RWVOL], 0, 0); - if (!code) { - VPRINT2("Renamed RO volume %s on host %s\n", - nameBuffer, - hostutil_GetNameByINet(entry-> - serverNumber[i])); - code = AFSVolEndTrans(aconn, tid, &rcode); - tid = 0; - if (code) { - fprintf(STDERR, - "Could not end transaction on volume %u\n", - entry->volumeId[ROVOL]); - error = code; - goto rvfail; - } - } else { - fprintf(STDERR, - "Could not set parameters on the ro volume %u\n", - entry->volumeId[ROVOL]); - error = code; - goto rvfail; - } - } - if (aconn) - rx_DestroyConnection(aconn); - aconn = (struct rx_connection *)0; - } - } - } - rvfail: - if (islocked) { - vcode = - ubik_Call(VL_ReleaseLock, cstruct, 0, entry->volumeId[RWVOL], - RWVOL, - LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP); - if (vcode) { - fprintf(STDERR, - "Could not unlock the VLDB entry for the volume %s %u\n", - entry->name, entry->volumeId[RWVOL]); - if (!error) - error = vcode; - } - } - if (tid) { - code = AFSVolEndTrans(aconn, tid, &rcode); - if (!code) - code = rcode; - if (code) { - fprintf(STDERR, "Failed to end transaction on a volume \n"); - if (!error) - error = code; - } - } - if (aconn) - rx_DestroyConnection(aconn); - PrintError("", error); - return error; - -} - -/*report on all the active transactions on volser */ -int -UV_VolserStatus(afs_int32 server, transDebugInfo ** rpntr, afs_int32 * rcount) -{ - struct rx_connection *aconn; - transDebugEntries transInfo; - afs_int32 code = 0; - - aconn = UV_Bind(server, AFSCONF_VOLUMEPORT); - transInfo.transDebugEntries_val = (transDebugInfo *) 0; - transInfo.transDebugEntries_len = 0; - code = AFSVolMonitor(aconn, &transInfo); - if (code) { - fprintf(STDERR, - "Could not access status information about the server\n"); - PrintError("", code); - if (transInfo.transDebugEntries_val) - free(transInfo.transDebugEntries_val); - if (aconn) - rx_DestroyConnection(aconn); - return code; - } else { - *rcount = transInfo.transDebugEntries_len; - *rpntr = transInfo.transDebugEntries_val; - if (aconn) - rx_DestroyConnection(aconn); - return 0; - } - - -} - -/*delete the volume without interacting with the vldb */ -int -UV_VolumeZap(afs_int32 server, afs_int32 part, afs_int32 volid) -{ - afs_int32 rcode, ttid, error, code; - struct rx_connection *aconn; - - code = 0; - error = 0; - ttid = 0; - - aconn = UV_Bind(server, AFSCONF_VOLUMEPORT); - code = AFSVolTransCreate(aconn, volid, part, ITOffline, &ttid); - if (code) { - fprintf(STDERR, "Could not start transaction on volume %lu\n", - (unsigned long)volid); - error = code; - goto zfail; - } - code = AFSVolDeleteVolume(aconn, ttid); - if (code) { - fprintf(STDERR, "Could not delete volume %lu\n", - (unsigned long)volid); - error = code; - goto zfail; - } - code = AFSVolEndTrans(aconn, ttid, &rcode); - ttid = 0; - if (!code) - code = rcode; - if (code) { - fprintf(STDERR, "Could not end transaction on volume %lu\n", - (unsigned long)volid); - error = code; - goto zfail; - } - zfail: - if (ttid) { - code = AFSVolEndTrans(aconn, ttid, &rcode); - if (!code) - code = rcode; - if (!error) - error = code; - } - PrintError("", error); - if (aconn) - rx_DestroyConnection(aconn); - return error; -} - -int -UV_SetVolume(afs_int32 server, afs_int32 partition, afs_int32 volid, - afs_int32 transflag, afs_int32 setflag, int sleeptime) -{ - struct rx_connection *conn = 0; - afs_int32 tid = 0; - afs_int32 code, error = 0, rcode; - - conn = UV_Bind(server, AFSCONF_VOLUMEPORT); - if (!conn) { - fprintf(STDERR, "SetVolumeStatus: Bind Failed"); - ERROR_EXIT(-1); - } - - code = AFSVolTransCreate(conn, volid, partition, transflag, &tid); - if (code) { - fprintf(STDERR, "SetVolumeStatus: TransCreate Failed\n"); - ERROR_EXIT(code); - } - - code = AFSVolSetFlags(conn, tid, setflag); - if (code) { - fprintf(STDERR, "SetVolumeStatus: SetFlags Failed\n"); - ERROR_EXIT(code); - } - - if (sleeptime) { -#ifdef AFS_PTHREAD_ENV - sleep(sleeptime); -#else - IOMGR_Sleep(sleeptime); -#endif - } - - error_exit: - if (tid) { - rcode = 0; - code = AFSVolEndTrans(conn, tid, &rcode); - if (code || rcode) { - fprintf(STDERR, "SetVolumeStatus: EndTrans Failed\n"); - if (!error) - error = (code ? code : rcode); - } - } - - if (conn) - rx_DestroyConnection(conn); - return (error); -} - -int -UV_SetVolumeInfo(afs_int32 server, afs_int32 partition, afs_int32 volid, - volintInfo * infop) -{ - struct rx_connection *conn = 0; - afs_int32 tid = 0; - afs_int32 code, error = 0, rcode; - - conn = UV_Bind(server, AFSCONF_VOLUMEPORT); - if (!conn) { - fprintf(STDERR, "SetVolumeInfo: Bind Failed"); - ERROR_EXIT(-1); - } - - code = AFSVolTransCreate(conn, volid, partition, ITOffline, &tid); - if (code) { - fprintf(STDERR, "SetVolumeInfo: TransCreate Failed\n"); - ERROR_EXIT(code); - } - - code = AFSVolSetInfo(conn, tid, infop); - if (code) { - fprintf(STDERR, "SetVolumeInfo: SetInfo Failed\n"); - ERROR_EXIT(code); - } - - error_exit: - if (tid) { - rcode = 0; - code = AFSVolEndTrans(conn, tid, &rcode); - if (code || rcode) { - fprintf(STDERR, "SetVolumeInfo: EndTrans Failed\n"); - if (!error) - error = (code ? code : rcode); - } - } - - if (conn) - rx_DestroyConnection(conn); - return (error); -} - -int -UV_GetSize(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart, - afs_int32 fromdate, struct volintSize *vol_size) -{ - struct rx_connection *aconn = (struct rx_connection *)0; - afs_int32 tid = 0, rcode = 0; - afs_int32 code, error = 0; - - - /* get connections to the servers */ - aconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT); - - VPRINT1("Starting transaction on volume %u...", afromvol); - code = AFSVolTransCreate(aconn, afromvol, afrompart, ITBusy, &tid); - EGOTO1(error_exit, code, - "Could not start transaction on the volume %u to be measured\n", - afromvol); - VDONE; - - VPRINT1("Getting size of volume on volume %u...", afromvol); - code = AFSVolGetSize(aconn, tid, fromdate, vol_size); - EGOTO(error_exit, code, "Could not start the measurement process \n"); - VDONE; - - error_exit: - if (tid) { - VPRINT1("Ending transaction on volume %u...", afromvol); - code = AFSVolEndTrans(aconn, tid, &rcode); - if (code || rcode) { - fprintf(STDERR, "Could not end transaction on the volume %u\n", - afromvol); - fprintf(STDERR, "error codes: %d and %d\n", code, rcode); - if (!error) - error = (code ? code : rcode); - } - VDONE; - } - if (aconn) - rx_DestroyConnection(aconn); - - PrintError("", error); - return (error); -} - -/*maps the host addresses in (present in network byte order) to - that in< new> (present in host byte order )*/ -void -MapNetworkToHost(struct nvldbentry *old, struct nvldbentry *new) -{ - int i, count; - - /*copy all the fields */ - strcpy(new->name, old->name); -/* new->volumeType = old->volumeType;*/ - new->nServers = old->nServers; - count = old->nServers; - if (count < NMAXNSERVERS) - count++; - for (i = 0; i < count; i++) { - new->serverNumber[i] = ntohl(old->serverNumber[i]); - new->serverPartition[i] = old->serverPartition[i]; - new->serverFlags[i] = old->serverFlags[i]; - } - new->volumeId[RWVOL] = old->volumeId[RWVOL]; - new->volumeId[ROVOL] = old->volumeId[ROVOL]; - new->volumeId[BACKVOL] = old->volumeId[BACKVOL]; - new->cloneId = old->cloneId; - new->flags = old->flags; -} - -/*maps the host entries in which are present in host byte order to network byte order */ -void -MapHostToNetwork(struct nvldbentry *entry) -{ - int i, count; - - count = entry->nServers; - if (count < NMAXNSERVERS) - count++; - for (i = 0; i < count; i++) { - entry->serverNumber[i] = htonl(entry->serverNumber[i]); - } -} diff --git a/src/volser/vsutils.c b/src/volser/vsutils.c deleted file mode 100644 index 0f825be9e..000000000 --- a/src/volser/vsutils.c +++ /dev/null @@ -1,674 +0,0 @@ -/* - * 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 - */ - -#include -#include - -RCSID - ("$Header: /cvs/openafs/src/volser/vsutils.c,v 1.16 2003/12/07 22:49:46 jaltman Exp $"); - -#include -#ifdef AFS_NT40_ENV -#include -#include -#else -#include -#include -#include -#include -#endif /* AFS_NT40_ENV */ -#include -#ifdef AFS_AIX_ENV -#include -#endif - -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "volser.h" -#include "volint.h" -#include "lockdata.h" - -struct ubik_client *cstruct; -static rxkad_level vsu_rxkad_level = rxkad_clear; - -static void -ovlentry_to_nvlentry(oentryp, nentryp) - struct vldbentry *oentryp; - struct nvldbentry *nentryp; -{ - register int i; - - memset(nentryp, 0, sizeof(struct nvldbentry)); - strncpy(nentryp->name, oentryp->name, sizeof(nentryp->name)); - for (i = 0; i < oentryp->nServers; i++) { - nentryp->serverNumber[i] = oentryp->serverNumber[i]; - nentryp->serverPartition[i] = oentryp->serverPartition[i]; - nentryp->serverFlags[i] = oentryp->serverFlags[i]; - } - nentryp->nServers = oentryp->nServers; - for (i = 0; i < MAXTYPES; i++) - nentryp->volumeId[i] = oentryp->volumeId[i]; - nentryp->cloneId = oentryp->cloneId; - nentryp->flags = oentryp->flags; -} - -static -nvlentry_to_ovlentry(nentryp, oentryp) - struct nvldbentry *nentryp; - struct vldbentry *oentryp; -{ - register int i; - - memset(oentryp, 0, sizeof(struct vldbentry)); - strncpy(oentryp->name, nentryp->name, sizeof(oentryp->name)); - if (nentryp->nServers > OMAXNSERVERS) { - /* - * The alternative is to store OMAXSERVERS but it's always better - * to know what's going on... - */ - return VL_BADSERVER; - } - for (i = 0; i < nentryp->nServers; i++) { - oentryp->serverNumber[i] = nentryp->serverNumber[i]; - oentryp->serverPartition[i] = nentryp->serverPartition[i]; - oentryp->serverFlags[i] = nentryp->serverFlags[i]; - } - oentryp->nServers = i; - for (i = 0; i < MAXTYPES; i++) - oentryp->volumeId[i] = nentryp->volumeId[i]; - oentryp->cloneId = nentryp->cloneId; - oentryp->flags = nentryp->flags; - return 0; -} - -static int newvlserver = 0; - -VLDB_CreateEntry(entryp) - struct nvldbentry *entryp; -{ - struct vldbentry oentry; - register int code; - - if (newvlserver == 1) { - tryold: - code = nvlentry_to_ovlentry(entryp, &oentry); - if (code) - return code; - code = ubik_Call(VL_CreateEntry, cstruct, 0, &oentry); - return code; - } - code = ubik_Call(VL_CreateEntryN, cstruct, 0, entryp); - if (!newvlserver) { - if (code == RXGEN_OPCODE) { - newvlserver = 1; /* Doesn't support new interface */ - goto tryold; - } else if (!code) { - newvlserver = 2; - } - } - return code; -} - -VLDB_GetEntryByID(volid, voltype, entryp) - afs_int32 volid, voltype; - struct nvldbentry *entryp; -{ - struct vldbentry oentry; - register int code; - - if (newvlserver == 1) { - tryold: - code = - ubik_Call(VL_GetEntryByID, cstruct, 0, volid, voltype, &oentry); - if (!code) - ovlentry_to_nvlentry(&oentry, entryp); - return code; - } - code = ubik_Call(VL_GetEntryByIDN, cstruct, 0, volid, voltype, entryp); - if (!newvlserver) { - if (code == RXGEN_OPCODE) { - newvlserver = 1; /* Doesn't support new interface */ - goto tryold; - } else if (!code) { - newvlserver = 2; - } - } - return code; -} - -VLDB_GetEntryByName(namep, entryp) - char *namep; - struct nvldbentry *entryp; -{ - struct vldbentry oentry; - register int code; - - if (newvlserver == 1) { - tryold: - code = ubik_Call(VL_GetEntryByNameO, cstruct, 0, namep, &oentry); - if (!code) - ovlentry_to_nvlentry(&oentry, entryp); - return code; - } - code = ubik_Call(VL_GetEntryByNameN, cstruct, 0, namep, entryp); - if (!newvlserver) { - if (code == RXGEN_OPCODE) { - newvlserver = 1; /* Doesn't support new interface */ - goto tryold; - } else if (!code) { - newvlserver = 2; - } - } - return code; -} - -VLDB_ReplaceEntry(volid, voltype, entryp, releasetype) - afs_int32 volid, voltype, releasetype; - struct nvldbentry *entryp; -{ - struct vldbentry oentry; - register int code; - - if (newvlserver == 1) { - tryold: - code = nvlentry_to_ovlentry(entryp, &oentry); - if (code) - return code; - code = - ubik_Call(VL_ReplaceEntry, cstruct, 0, volid, voltype, &oentry, - releasetype); - return code; - } - code = - ubik_Call(VL_ReplaceEntryN, cstruct, 0, volid, voltype, entryp, - releasetype); - if (!newvlserver) { - if (code == RXGEN_OPCODE) { - newvlserver = 1; /* Doesn't support new interface */ - goto tryold; - } else if (!code) { - newvlserver = 2; - } - } - return code; -} - - - -VLDB_ListAttributes(attrp, entriesp, blkentriesp) - VldbListByAttributes *attrp; - afs_int32 *entriesp; - nbulkentries *blkentriesp; -{ - bulkentries arrayEntries; - register int code, i; - - if (newvlserver == 1) { - tryold: - memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */ - code = - ubik_Call(VL_ListAttributes, cstruct, 0, attrp, entriesp, - &arrayEntries); - if (!code) { - blkentriesp->nbulkentries_val = - (nvldbentry *) malloc(*entriesp * sizeof(struct nvldbentry)); - for (i = 0; i < *entriesp; i++) { /* process each entry */ - ovlentry_to_nvlentry(&arrayEntries.bulkentries_val[i], - &blkentriesp->nbulkentries_val[i]); - } - } - if (arrayEntries.bulkentries_val) - free(arrayEntries.bulkentries_val); - return code; - } - code = - ubik_Call(VL_ListAttributesN, cstruct, 0, attrp, entriesp, - blkentriesp); - if (!newvlserver) { - if (code == RXGEN_OPCODE) { - newvlserver = 1; /* Doesn't support new interface */ - goto tryold; - } else if (!code) { - newvlserver = 2; - } - } - return code; -} - -VLDB_ListAttributesN2(attrp, name, thisindex, nentriesp, blkentriesp, - nextindexp) - VldbListByAttributes *attrp; - char *name; - afs_int32 thisindex; - afs_int32 *nentriesp; - nbulkentries *blkentriesp; - afs_int32 *nextindexp; -{ - afs_int32 code; - - code = - ubik_Call(VL_ListAttributesN2, cstruct, 0, attrp, (name ? name : ""), - thisindex, nentriesp, blkentriesp, nextindexp); - return code; -} - - -static int vlserverv4 = -1; -struct cacheips { - afs_int32 server; - afs_int32 count; - afs_uint32 addrs[16]; -}; -/* - * Increase cache size. This avoids high CPU usage by the vlserver - * in environments where there are more than 16 fileservers in the - * cell. - */ -#define GETADDRUCACHESIZE 64 -struct cacheips cacheips[GETADDRUCACHESIZE]; -int cacheip_index = 0; - -VLDB_IsSameAddrs(serv1, serv2, errorp) - afs_int32 serv1, serv2, *errorp; -{ - register int code; - ListAddrByAttributes attrs; - bulkaddrs addrs; - afs_uint32 *addrp, nentries, unique, i, j, f1, f2; - afsUUID uuid; - static int initcache = 0; - - *errorp = 0; - - if (serv1 == serv2) - return 1; - if (vlserverv4 == 1) { - return 0; - } - if (!initcache) { - for (i = 0; i < GETADDRUCACHESIZE; i++) { - cacheips[i].server = cacheips[i].count = 0; - } - initcache = 1; - } - - /* See if it's cached */ - for (i = 0; i < GETADDRUCACHESIZE; i++) { - f1 = f2 = 0; - for (j = 0; j < cacheips[i].count; j++) { - if (serv1 == cacheips[i].addrs[j]) - f1 = 1; - else if (serv2 == cacheips[i].addrs[j]) - f2 = 1; - - if (f1 && f2) - return 1; - } - if (f1 || f2) - return 0; - if (cacheips[i].server == serv1) - return 0; - } - - memset(&attrs, 0, sizeof(attrs)); - attrs.Mask = VLADDR_IPADDR; - attrs.ipaddr = serv1; - memset(&addrs, 0, sizeof(addrs)); - memset(&uuid, 0, sizeof(uuid)); - code = - ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid, &unique, &nentries, - &addrs); - if (vlserverv4 == -1) { - if (code == RXGEN_OPCODE) { - vlserverv4 = 1; /* Doesn't support new interface */ - return 0; - } else if (!code) { - vlserverv4 = 2; - } - } - if (code == VL_NOENT) - return 0; - if (code) { - *errorp = code; - return 0; - } - - code = 0; - if (nentries > GETADDRUCACHESIZE) - nentries = GETADDRUCACHESIZE; /* safety check; should not happen */ - if (++cacheip_index >= GETADDRUCACHESIZE) - cacheip_index = 0; - cacheips[cacheip_index].server = serv1; - cacheips[cacheip_index].count = nentries; - addrp = addrs.bulkaddrs_val; - for (i = 0; i < nentries; i++, addrp++) { - cacheips[cacheip_index].addrs[i] = *addrp; - if (serv2 == *addrp) { - code = 1; - } - } - return code; -} - - -#ifdef notdef -afs_int32 -subik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, - p11, p12, p13, p14, p15, p16) - register struct ubik_client *aclient; - int (*aproc) (); - afs_int32 aflags; - afs_int32 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, - p15, p16; -{ - struct vldbentry vldbentry; - register int code, (*nproc) (); - - if (newvlserver == 1) { - } - code = - ubik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9, - p10, p11, p12, p13, p14, p15, p16); - if (!newvlserver) { - if (code == RXGEN_OPCODE) { - newvlserver = 1; /* Doesn't support new interface */ - } else if (!code) { - newvlserver = 2; - } - } -} -#endif /* notdef */ - - -/* - Set encryption. If 'cryptflag' is nonzero, encrpytion is turned on - for authenticated connections; if zero, encryption is turned off. - Calling this function always results in a level of at least rxkad_auth; - to get a rxkad_clear connection, simply don't call this. -*/ -void -vsu_SetCrypt(cryptflag) - int cryptflag; -{ - if (cryptflag) { - vsu_rxkad_level = rxkad_crypt; - } else { - vsu_rxkad_level = rxkad_auth; - } -} - - -/* - Get the appropriate type of ubik client structure out from the system. -*/ -afs_int32 -vsu_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp, secproc) - int noAuthFlag; - int (*secproc) (); - char *cellName; - struct ubik_client **uclientp; - char *confDir; - afs_int32 sauth; -{ - afs_int32 code, scIndex, i; - struct afsconf_cell info; - struct afsconf_dir *tdir; - struct ktc_principal sname; - struct ktc_token ttoken; - struct rx_securityClass *sc; - static struct rx_connection *serverconns[VLDB_MAXSERVERS]; - char cellstr[64]; - - - code = rx_Init(0); - if (code) { - fprintf(STDERR, "vsu_ClientInit: could not initialize rx.\n"); - return code; - } - rx_SetRxDeadTime(90); - - if (sauth) { /* -localauth */ - tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); - if (!tdir) { - fprintf(STDERR, - "vsu_ClientInit: Could not process files in configuration directory (%s).\n", - AFSDIR_SERVER_ETC_DIRPATH); - return -1; - } - code = afsconf_ClientAuth(tdir, &sc, &scIndex); /* sets sc,scIndex */ - if (code) { - fprintf(STDERR, - "vsu_ClientInit: Could not get security object for -localAuth\n"); - return -1; - } - code = - afsconf_GetCellInfo(tdir, tdir->cellName, AFSCONF_VLDBSERVICE, - &info); - if (code) { - fprintf(STDERR, - "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n", - cellName, AFSDIR_SERVER_ETC_DIRPATH, - AFSDIR_CELLSERVDB_FILE); - exit(1); - } - } else { /* not -localauth */ - tdir = afsconf_Open(confDir); - if (!tdir) { - fprintf(STDERR, - "vsu_ClientInit: Could not process files in configuration directory (%s).\n", - confDir); - return -1; - } - - if (!cellName) { - code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr)); - if (code) { - fprintf(STDERR, - "vsu_ClientInit: can't get local cellname, check %s/%s\n", - confDir, AFSDIR_THISCELL_FILE); - exit(1); - } - cellName = cellstr; - } - - code = - afsconf_GetCellInfo(tdir, cellName, AFSCONF_VLDBSERVICE, &info); - if (code) { - fprintf(STDERR, - "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n", - cellName, confDir, AFSDIR_CELLSERVDB_FILE); - exit(1); - } - if (noAuthFlag) /* -noauth */ - scIndex = 0; - else { /* not -noauth */ - strcpy(sname.cell, info.name); - sname.instance[0] = 0; - strcpy(sname.name, "afs"); - code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL); - if (code) { /* did not get ticket */ - fprintf(STDERR, - "vsu_ClientInit: Could not get afs tokens, running unauthenticated.\n"); - scIndex = 0; - } else { /* got a ticket */ - scIndex = 2; - if ((ttoken.kvno < 0) || (ttoken.kvno > 255)) { - fprintf(STDERR, - "vsu_ClientInit: funny kvno (%d) in ticket, proceeding\n", - ttoken.kvno); - } - } - } - - switch (scIndex) { - case 0: - sc = rxnull_NewClientSecurityObject(); - break; - case 2: - sc = rxkad_NewClientSecurityObject(vsu_rxkad_level, - &ttoken.sessionKey, - ttoken.kvno, ttoken.ticketLen, - ttoken.ticket); - break; - default: - fprintf(STDERR, "vsu_ClientInit: unsupported security index %d\n", - scIndex); - exit(1); - break; - } - } - - afsconf_Close(tdir); - - if (secproc) /* tell UV module about default authentication */ - (*secproc) (sc, scIndex); - if (info.numServers > VLDB_MAXSERVERS) { - fprintf(STDERR, - "vsu_ClientInit: info.numServers=%d (> VLDB_MAXSERVERS=%d)\n", - info.numServers, VLDB_MAXSERVERS); - exit(1); - } - for (i = 0; i < info.numServers; i++) { - serverconns[i] = - rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, - info.hostAddr[i].sin_port, USER_SERVICE_ID, sc, - scIndex); - } - *uclientp = 0; - code = ubik_ClientInit(serverconns, uclientp); - if (code) { - fprintf(STDERR, "vsu_ClientInit: ubik client init failed.\n"); - return code; - } - return 0; -} - - -/*extract the name of volume without readonly or backup suffixes - * and return the result as . - */ -int -vsu_ExtractName(rname, name) - char rname[], name[]; -{ - char sname[VOLSER_OLDMAXVOLNAME + 1]; - int total; - - strncpy(sname, name, sizeof(sname)); - sname[sizeof(sname) - 1] = '\0'; - total = strlen(sname); - if (!strcmp(&sname[total - 9], ".readonly")) { - /*discard the last 8 chars */ - sname[total - 9] = '\0'; - strcpy(rname, sname); - return 0; - } else if (!strcmp(&sname[total - 7], ".backup")) { - /*discard last 6 chars */ - sname[total - 7] = '\0'; - strcpy(rname, sname); - return 0; - } else { - strncpy(rname, name, VOLSER_OLDMAXVOLNAME); - rname[VOLSER_OLDMAXVOLNAME] = '\0'; - return -1; - } -} - - -/* returns 0 if failed */ -afs_uint32 -vsu_GetVolumeID(astring, acstruct, errp) - struct ubik_client *acstruct; - afs_int32 *errp; - char *astring; -{ - afs_uint32 tc, value; - - char *str, *ptr, volname[VOLSER_OLDMAXVOLNAME + 1]; - int tryname, curval; - struct nvldbentry entry; - afs_int32 vcode = 0; - int total; - - *errp = 0; - total = strlen(astring); - str = astring; - ptr = astring; - tryname = 0; - while ((curval = *str++)) { - if (curval < '0' || curval > '9') - tryname = 1; - } - - if (tryname) { - vsu_ExtractName(volname, astring); - vcode = VLDB_GetEntryByName(volname, &entry); - if (!vcode) { - if (!strcmp(&astring[total - 9], ".readonly")) - return entry.volumeId[ROVOL]; - else if ((!strcmp(&astring[total - 7], ".backup"))) - return entry.volumeId[BACKVOL]; - else - return (entry.volumeId[RWVOL]); - } else { - *errp = vcode; - return 0; /* can't find volume */ - } - } - - value = 0; - while ((tc = *astring++)) { - if (tc & 0x80) { - if (!tryname) - fprintf(STDERR, "goofed in volid \n"); - else { - fprintf(STDERR, "Could not get entry from vldb for %s\n", - ptr); - PrintError("", vcode); - } - *errp = EINVAL; - return 0; - } - if (tc < '0' || tc > '9') { - if (!tryname) - fprintf(STDERR, - "internal error: out of range char in vol ID\n"); - else { - fprintf(STDERR, "Could not get entry from vldb for %s\n", - ptr); - PrintError("", vcode); - } - *errp = ERANGE; - return 0; - } - value *= 10; - value += (tc - '0'); - } - return value; -} -- 2.39.5