+++ /dev/null
-AFS_component_version_number.c
-Makefile
-restorevol
-volerr.c
-volint.cs.c
-volint.h
-volint.ss.c
-volint.xdr.c
-volser.h
-volserver
-vos
+++ /dev/null
-# 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
+++ /dev/null
-# 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:
-
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/common.c,v 1.10 2003/11/15 04:59:16 shadow Exp $");
-
-#include <stdio.h>
-#include <afs/afsutil.h>
-#include <afs/com_err.h>
-
-#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;
-}
+++ /dev/null
-/*
- * 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 "!"
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/dumpstuff.c,v 1.25 2003/11/23 04:53:44 jaltman Exp $");
-
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <errno.h>
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#else
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#include <sys/stat.h>
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include <afs/assert.h>
-#endif /* AFS_PTHREAD_ENV */
-#include <rx/xdr.h>
-#include <rx/rx.h>
-#include <afs/afsint.h>
-#include <afs/nfs.h>
-#include <afs/errors.h>
-#include <lock.h>
-#include <lwp.h>
-#include <afs/ihandle.h>
-#include <afs/vnode.h>
-#include <afs/volume.h>
-#include <afs/partition.h>
-#include "dump.h"
-#include <afs/fssync.h>
-#include <afs/acl.h>
-#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 <sys/statfs.h>
- 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;
-}
+++ /dev/null
-/*
- * 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_ */
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/lockprocs.c,v 1.8 2003/07/15 23:17:48 shadow Exp $");
-
-#include <sys/types.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#include <afs/voldefs.h>
-#include <rx/xdr.h>
-#include <rx/rx.h>
-#include <afs/vlserver.h>
-#include <afs/nfs.h>
-#include <afs/afsint.h>
-#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 <ahead>*/
-Lp_QInit(ahead)
- struct qHead *ahead;
-{
- ahead->count = 0;
- ahead->next = NULL;
-}
-
-/*add <elem> in front of queue <ahead> */
-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 <ahead>, free
-*the space used by that element . <success> 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--;
- }
-}
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/physio.c,v 1.11 2003/12/09 23:07:57 shadow Exp $");
-
-#include <sys/types.h>
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#else
-#include <sys/file.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#ifdef AFS_SUN5_ENV
-#include <sys/fcntl.h>
-#endif
-#include <errno.h>
-#include <rx/xdr.h>
-#include <rx/rx.h>
-#include <stdio.h>
-#include <afs/afsint.h>
-#include <afs/nfs.h>
-#include <afs/assert.h>
-#include <afs/dir.h>
-#include <afs/ihandle.h>
-#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);
-}
+++ /dev/null
-/*
- * 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 <dump file>]
- * [-dir <restore dir>]
- * [-extension <name extension>]
- * [-mountpoint <mount point root>]
- * [-umask <mode mask>]
- *
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/restorevol.c,v 1.13 2003/12/05 08:36:06 shadow Exp $");
-
-#include <afs/afsint.h>
-#include <afs/nfs.h>
-#include <lock.h>
-#include <afs/ihandle.h>
-#include <afs/vnode.h>
-#include <afs/volume.h>
-#include "volint.h"
-#include "dump.h"
-#include <afs/cmd.h>
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <stdio.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#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> */
- 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 <rootdir> */
- 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 <ext> */
- }
-
- /* 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);
-}
+++ /dev/null
-/*
- * 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 <afs/afssyscalls.h>
-
-typedef struct DirHandle {
- int dirh_volume;
- int dirh_device;
- Inode dirh_inode;
- afs_int32 dirh_cacheCheck;
- IHandle_t *dirh_handle;
-} DirHandle;
+++ /dev/null
-# 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
+++ /dev/null
-/*
- * 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;
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/volmain.c,v 1.18 2003/12/07 22:49:44 jaltman Exp $");
-
-#include <sys/types.h>
-#ifdef AFS_NT40_ENV
-#include <time.h>
-#include <fcntl.h>
-#include <windows.h>
-#include <WINNT/afsevent.h>
-#else
-#include <sys/time.h>
-#include <sys/file.h>
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#include <rx/xdr.h>
-#include <afs/afsint.h>
-#include <stdio.h>
-#include <signal.h>
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include <afs/assert.h>
-#endif /* AFS_PTHREAD_ENV */
-#include <afs/prs_fs.h>
-#include <afs/nfs.h>
-#include <lwp.h>
-#include <lock.h>
-#include <afs/afssyscalls.h>
-#include <afs/ihandle.h>
-#ifdef AFS_NT40_ENV
-#include <afs/ntops.h>
-#endif
-#include <afs/vnode.h>
-#include <afs/volume.h>
-#include <afs/partition.h>
-#include <rx/rx.h>
-#include <rx/rx_globals.h>
-#include <afs/auth.h>
-#include <rx/rxkad.h>
-#include <afs/cellconfig.h>
-#include <afs/keys.h>
-#include <ubik.h>
-
-#include "volser.h"
-#include <errno.h>
-#include <afs/audit.h>
-#include <afs/afsutil.h>
-
-/*@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 <integer value>\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 <number of processes>] "
- "[-udpsize <size of socket buffer in bytes>] "
- "[-syslog[=FACILITY]] "
- "[-enable_peer_stats] [-enable_process_stats] "
- "[-help]\n");
-#else
- printf("Usage: volserver [-log] [-p <number of processes>] "
- "[-udpsize <size of socket buffer in bytes>] "
- "[-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?");
-}
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.33 2004/01/01 06:22:31 shadow Exp $");
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <errno.h>
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#include <winsock2.h>
-#else
-#include <sys/file.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
-#include <dirent.h>
-#include <sys/stat.h>
-#include <rx/xdr.h>
-#include <rx/rx.h>
-#include <rx/rxkad.h>
-#include <afs/afsint.h>
-#include <signal.h>
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include <afs/assert.h>
-#endif /* AFS_PTHREAD_ENV */
-#include <afs/prs_fs.h>
-#include <afs/nfs.h>
-#include <lwp.h>
-#include <lock.h>
-#include <afs/auth.h>
-#include <afs/cellconfig.h>
-#include <afs/keys.h>
-#include <ubik.h>
-#include <afs/ihandle.h>
-#ifdef AFS_NT40_ENV
-#include <afs/ntops.h>
-#endif
-#include <afs/vnode.h>
-#include <afs/volume.h>
-#include <afs/partition.h>
-#include "vol.h"
-#include <afs/fssync.h>
-#include <afs/acl.h>
-#include "afs/audit.h"
-#include <afs/dir.h>
-
-#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 .. <whatever> */
- 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*<id>.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 <volid> */
-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;
-}
+++ /dev/null
-/*
- * 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 <assert.h>
-#include <pthread.h>
-#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_ */
+++ /dev/null
-/*
- * 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"
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/voltrans.c,v 1.10 2003/11/22 02:57:04 shadow Exp $");
-
-#ifdef AFS_NT40_ENV
-#include <afs/afsutil.h>
-#else
-#include <sys/time.h>
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <errno.h>
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#include <winsock2.h>
-#else
-#include <sys/file.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#endif
-#include <dirent.h>
-#include <sys/stat.h>
-#include <afs/afsint.h>
-#include <signal.h>
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include <afs/assert.h>
-#endif /* AFS_PTHREAD_ENV */
-#include <afs/prs_fs.h>
-#include <afs/nfs.h>
-#include <lwp.h>
-#include <lock.h>
-#include <afs/auth.h>
-#include <afs/cellconfig.h>
-#include <afs/keys.h>
-#include <rx/rx.h>
-#include <ubik.h>
-#include <afs/ihandle.h>
-#ifdef AFS_NT40_ENV
-#include <afs/ntops.h>
-#endif
-#include <afs/vnode.h>
-#include <afs/volume.h>
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#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);
-}
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/vos.c,v 1.38 2004/04/08 22:20:39 jaltman Exp $");
-
-#include <sys/types.h>
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#include <io.h>
-#include <winsock2.h>
-#else
-#include <sys/time.h>
-#include <sys/file.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-#include <sys/stat.h>
-#ifdef AFS_AIX_ENV
-#include <sys/statfs.h>
-#endif
-#include <errno.h>
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
-#include <lock.h>
-#include <afs/stds.h>
-#include <rx/xdr.h>
-#include <rx/rx.h>
-#include <rx/rx_globals.h>
-#include <afs/nfs.h>
-#include <afs/vlserver.h>
-#include <afs/auth.h>
-#include <afs/cellconfig.h>
-#include <afs/keys.h>
-#include <afs/afsutil.h>
-#include <ubik.h>
-#include <afs/afsint.h>
-#include <afs/cmd.h>
-#include <afs/usd.h>
-#include <rx/rxkad.h>
-#include "volser.h"
-#include "volint.h"
-#include "lockdata.h"
-#ifdef AFS_AIX32_ENV
-#include <signal.h>
-#endif
-#include "volser_prototypes.h"
-
-#ifdef HAVE_POSIX_REGEX
-#include <regex.h>
-#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 <filename> 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 <name> 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 <fd> and <blksize> to Rx Stream
- * associated with <call> */
-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 <call> stream into file associated
- * with <fd> <blksize>
- */
-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 <server> and <part> to the correct values depending on
- * <voltype> and <entry> */
-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 <quota> */
- 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 <addr>' 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("<unknown>\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));
-}
+++ /dev/null
-/*
- * 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"
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.30 2004/01/08 21:54:10 shadow Exp $");
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef AFS_AIX_ENV
-#include <sys/statfs.h>
-#endif
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#include <winsock2.h>
-#else
-#include <sys/file.h>
-#include <netinet/in.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
-#include <lock.h>
-#include <afs/voldefs.h>
-#include <rx/xdr.h>
-#include <rx/rx.h>
-#include <afs/vlserver.h>
-#include <afs/nfs.h>
-#include <afs/auth.h>
-#include <afs/cellconfig.h>
-#include <afs/keys.h>
-#include <ubik.h>
-#include <afs/afsint.h>
-#include "volser.h"
-#include "volint.h"
-#include "lockdata.h"
-#include <afs/com_err.h>
-#include <rx/rxkad.h>
-#include <afs/kautils.h>
-#include <afs/cmd.h>
-#include <errno.h>
-#define ERRCODE_RANGE 8 /* from error_table.h */
-#define CLOCKSKEW 2 /* not really skew, but resolution */
-
-/* for UV_MoveVolume() recovery */
-
-#include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
-#include <setjmp.h>
-
-#include <volser_prototypes.h>
-
-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 <partId> into partition name <partName>*/
-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 <port> <aserver> */
-/* 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 <okvol> is allright(indicated by beibg able to
- * start a transaction, delete the <delvol> */
-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 <entry> */
-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 <pname> on <server> in <partition> */
-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 <anewid>*/
-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 <anewid>*/
-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 <volid>on <aserver> <apart>
- * 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 <afromvol> on <afromserver> <afrompart> to <atoserver>
- * <atopart>. 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 <afromvol> from <afromserver> <afrompart> to <atoserver>
- * <atopart>. The new volume is named by <atovolname>. The new volume
- * has ID <atovolid> 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 <avolid> on <aserver> and <apart>
- * 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 <avolid> on <aserver> and <apart>
- * using volume ID <acloneid>, or a new ID allocated from the VLDB.
- * The new volume is named by <aname>, or by appending ".clone" to
- * the existing name if <aname> 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 <afromvol> on <afromserver> <afrompart> 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 <afromvol> on <afromserver> and
- * <afrompart> to <afilename> starting from <fromdate>.
- * 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 <afromvol> on <afromserver> and
- * <afrompart>, and then dump the clone volume to
- * <afilename> starting from <fromdate>.
- * 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 <tovolid> <tovolname> on <toserver> <topart> from
- * the dump file <afilename>. 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 <volid> */
-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 <server> and <part> as a readonly replication site for <volid>
-*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 <server> <part> as read only site for <volid> 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 <server> <part> as read/write site for <volid> 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 <aserver> */
-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 <aserver> and <apart>. 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 <volid> on <aserver> and <apart> */
-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 <aserver> <apart>(if flags = 1) <avolid>.
- * 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 <aserver> and,
- * optionally, <apart>.
- */
-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 <entry> 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 <aserver> <apart>(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 <oldname> to <newname>, 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 <old > (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 <entry> 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]);
- }
-}
+++ /dev/null
-/*
- * 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 <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header: /cvs/openafs/src/volser/vsutils.c,v 1.16 2003/12/07 22:49:46 jaltman Exp $");
-
-#include <afs/stds.h>
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#include <winsock2.h>
-#else
-#include <sys/types.h>
-#include <sys/file.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#endif /* AFS_NT40_ENV */
-#include <sys/stat.h>
-#ifdef AFS_AIX_ENV
-#include <sys/statfs.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
-#include <errno.h>
-#include <lock.h>
-#include <rx/xdr.h>
-#include <rx/rx.h>
-#include <rx/rx_globals.h>
-#include <afs/nfs.h>
-#include <afs/vlserver.h>
-#include <afs/auth.h>
-#include <afs/cellconfig.h>
-#include <afs/keys.h>
-#include <ubik.h>
-#include <afs/afsint.h>
-#include <afs/cmd.h>
-#include <rx/rxkad.h>
-#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 <name> without readonly or backup suffixes
- * and return the result as <rname>.
- */
-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;
-}