extern pthread_mutex_t vol_trans_mutex;
extern pthread_cond_t vol_put_volume_cond;
extern pthread_cond_t vol_sleep_cond;
+extern ih_init_params vol_io_params;
extern int vol_attach_threads;
#ifdef VOL_LOCK_DEBUG
extern pthread_t vol_glock_holder;
*/
typedef enum {
fileServer = 1, /**< the fileserver process */
- volumeUtility = 2, /**< volserver, or a
- * single volume salvager (non-dafs) */
+ volumeUtility = 2, /**< any miscellaneous volume utility */
salvager = 3, /**< standalone whole-partition salvager */
salvageServer = 4, /**< dafs online salvager */
- debugUtility = 5 /**< fssync-debug or similar utility */
+ debugUtility = 5, /**< fssync-debug or similar utility */
+ volumeServer = 6, /**< the volserver process */
+ volumeSalvager = 7, /**< the standalone single-volume salvager */
} ProgramType;
extern ProgramType programType; /* The type of program using the package */
#endif /* AFS_DEMAND_ATTACH_FS */
+typedef struct VolumePackageOptions {
+ afs_uint32 nLargeVnodes; /**< size of large vnode cache */
+ afs_uint32 nSmallVnodes; /**< size of small vnode cache */
+ afs_uint32 volcache; /**< size of volume header cache */
+
+ afs_int32 canScheduleSalvage; /**< can we schedule salvages? (DAFS) */
+ /* (if 'no', we will just error out if we
+ * find a bad vol) */
+ afs_int32 canUseFSSYNC; /**< can we use the FSSYNC channel? */
+ afs_int32 canUseSALVSYNC; /**< can we use the SALVSYNC channel? (DAFS) */
+} VolumePackageOptions;
/* Magic numbers and version stamps for each type of file */
#define VOLUMEHEADERMAGIC ((bit32)0x88a1bb3c)
afs_uint32 last_vol_op; /**< unix timestamp of last volume operation */
} VolumeStats;
+
+#define SALVAGE_PRIO_UPDATE_INTERVAL 3 /**< number of seconds between prio updates */
+#define SALVAGE_COUNT_MAX 16 /**< number of online salvages we
+ * allow before moving the volume
+ * into a permanent error state
+ *
+ * once this threshold is reached,
+ * the operator will have to manually
+ * issue a 'bos salvage' to bring
+ * the volume back online
+ */
+
/**
* DAFS online salvager state.
*/
unsigned bitNumber);
extern int VolumeNumber(char *name);
extern char *VolumeExternalName(VolumeId volumeId);
+extern int VolumeExternalName_r(VolumeId volumeId, char *name, size_t len);
extern Volume *VAttachVolumeByName(Error * ec, char *partition, char *name,
int mode);
extern Volume *VAttachVolumeByName_r(Error * ec, char *partition, char *name,
extern void VCloseVnodeFiles_r(Volume * vp);
extern struct DiskPartition64 *VGetPartition(char *name, int abortp);
extern struct DiskPartition64 *VGetPartition_r(char *name, int abortp);
-extern int VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes,
- afs_uint32 nSmallVnodes, int connect, afs_uint32 volcache);
+extern void VOptDefaults(ProgramType pt, VolumePackageOptions * opts);
+extern int VInitVolumePackage2(ProgramType pt, VolumePackageOptions * opts);
extern int VInitAttachVolumes(ProgramType pt);
extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
char **namep);
extern char *vol_DevName(dev_t adev, char *wpath);
+struct VLockFile;
+extern void VLockFileInit(struct VLockFile *lf, const char *path);
+extern int VLockFileLock(struct VLockFile *lf, afs_uint32 offset,
+ int locktype, int nonblock);
+extern void VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset);
+
#ifdef AFS_DEMAND_ATTACH_FS
extern Volume *VPreAttachVolumeByName(Error * ec, char *partition, char *name);
extern Volume *VPreAttachVolumeByName_r(Error * ec, char *partition, char *name);
extern void VLRU_SetOptions(int option, afs_uint32 val);
extern int VSetVolHashSize(int logsize);
extern int VRequestSalvage_r(Error * ec, Volume * vp, int reason, int flags);
+extern int VUpdateSalvagePriority_r(Volume * vp);
extern int VRegisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
extern int VDeregisterVolOp_r(Volume * vp);
extern void VCancelReservation_r(Volume * vp);
extern int VChildProcReconnectFS_r(void);
extern void VOfflineForVolOp_r(Error *ec, Volume *vp, char *message);
+
+struct VDiskLock;
+extern void VDiskLockInit(struct VDiskLock *dl, struct VLockFile *lf,
+ afs_uint32 offset);
+extern int VGetDiskLock(struct VDiskLock *dl, int locktype, int nonblock);
+extern void VReleaseDiskLock(struct VDiskLock *dl, int locktype);
#endif /* AFS_DEMAND_ATTACH_FS */
extern int VVolOpLeaveOnline_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
extern int VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
extern void VPurgeVolume(Error * ec, Volume * vp);
+extern afs_int32 VCanScheduleSalvage(void);
+extern afs_int32 VCanUseFSSYNC(void);
+extern afs_int32 VCanUseSALVSYNC(void);
+extern afs_int32 VReadVolumeDiskHeader(VolumeId volid,
+ struct DiskPartition64 * dp,
+ VolumeDiskHeader_t * hdr);
+extern afs_int32 VWriteVolumeDiskHeader(VolumeDiskHeader_t * hdr,
+ struct DiskPartition64 * dp);
+extern afs_int32 VCreateVolumeDiskHeader(VolumeDiskHeader_t * hdr,
+ struct DiskPartition64 * dp);
+extern afs_int32 VDestroyVolumeDiskHeader(struct DiskPartition64 * dp,
+ VolumeId volid, VolumeId parent);
+
+/**
+ * VWalkVolumeHeaders header callback.
+ *
+ * @param[in] dp disk partition
+ * @param[in] name full path to the .vol header file
+ * @param[in] hdr the header data that was read from the .vol header
+ * @param[in] last 1 if this is the last attempt to read the vol header, 0
+ * otherwise. DAFS VWalkVolumeHeaders will retry reading the
+ * header once, if a non-fatal error occurs when reading the
+ * header, or if this function returns a positive error code.
+ * So, if there is a problem, this function will be called
+ * first with last=0, then with last=1, then the error function
+ * callback will be called. For non-DAFS, this is always 1.
+ * @param[in] rock the rock passed to VWalkVolumeHeaders
+ *
+ * @return operation status
+ * @retval 0 success
+ * @retval negative a fatal error that should stop the walk immediately
+ * @retval positive an error with the volume header was encountered; the walk
+ * should continue, but the error function should be called on this
+ * header
+ *
+ * @see VWalkVolumeHeaders
+ */
+typedef int (*VWalkVolFunc)(struct DiskPartition64 *dp, const char *name,
+ struct VolumeDiskHeader *hdr, int last,
+ void *rock);
+/**
+ * VWalkVolumeHeaders error callback.
+ *
+ * This is called from VWalkVolumeHeaders when an invalid or otherwise
+ * problematic volume header is encountered. It is typically implemented as a
+ * wrapper to unlink the .vol file.
+ *
+ * @param[in] dp disk partition
+ * @param[in] name full path to the .vol header file
+ * @param[in] hdr header read in from the .vol file, or NULL if it could not
+ * be read
+ * @param[in] rock rock passed to VWalkVolumeHeaders
+ *
+ * @see VWalkVolumeHeaders
+ */
+typedef void (*VWalkErrFunc)(struct DiskPartition64 *dp, const char *name,
+ struct VolumeDiskHeader *hdr, void *rock);
+extern int VWalkVolumeHeaders(struct DiskPartition64 *dp, const char *partpath,
+ VWalkVolFunc volfunc, VWalkErrFunc errfunc,
+ void *rock);
/* Naive formula relating number of file size to number of 1K blocks in file */
/* Note: we charge 1 block for 0 length files so the user can't store
#define V_pref(vp,nearInode) nearInode = 0
#endif /* NEARINODE_HINT */
+hdr_static_inline(unsigned int)
+afs_printable_VolumeId_u(VolumeId d) { return (unsigned int) d; }
+
+hdr_static_inline(unsigned int)
+afs_printable_VnodeId_u(VnodeId d) { return (unsigned int) d; }
+
#endif /* __volume_h */