From 2a13973985bc7e190364d208c590ec42dbccf81b Mon Sep 17 00:00:00 2001 From: Michael Meffie Date: Thu, 11 Jun 2015 13:14:27 -0400 Subject: [PATCH] libafs: vldb cache timeout option (-volume-ttl) The unix cache manager caches VLDB information for read-only volumes as long as a volume callback is held for a read-only volume. The volume callback may be held as long as files in the read-only volume are being accessed. The cache manager caches VLDB information for read/write volumes as long as volume level errors (such as VMOVED) are not returned by a fileserver while accessing files within the volume. Add a new option to set the maximum amount of time VLDB information will be cached, even if a callback is still held for a read-only volume, or no volume errors have been encounted while accessing files in read/write volumes. This avoids situations where the vldb information is cached indefinitely for read-only and read/write volumes. Instead, the VL servers will be periodically probed for volume information. Change-Id: I5f2a57cdaf5cbe7b1bc0440ed6408226cc988fed Reviewed-on: https://gerrit.openafs.org/11898 Tested-by: BuildBot Reviewed-by: Michael Meffie Reviewed-by: Benjamin Kaduk --- doc/man-pages/pod8/afsd.pod | 16 ++++++++++++++++ src/afs/afs.h | 4 ++++ src/afs/afs_call.c | 9 +++++++++ src/afs/afs_volume.c | 19 +++++++++++++++++-- src/afsd/afsd.c | 16 ++++++++++++++++ src/config/afs_args.h | 1 + 6 files changed, 63 insertions(+), 2 deletions(-) diff --git a/doc/man-pages/pod8/afsd.pod b/doc/man-pages/pod8/afsd.pod index dd48a161f..6114a7e5c 100644 --- a/doc/man-pages/pod8/afsd.pod +++ b/doc/man-pages/pod8/afsd.pod @@ -34,6 +34,7 @@ B [B<-afsdb>] [B<-backuptree>] [B<-disable-dynamic-vcaches>] S<<< [B<-volumes> >] >>> [B<-waitclose>] [B<-rxmaxfrags> >] + S<<< [B<-volume-ttl> >] >>> =for html @@ -753,6 +754,21 @@ affected in previous versions of the Cache Manager, to perform synchronous writes to the File Server, is now the default behavior. To perform asynchronous writes in certain cases, use the B command. +=item B<-volume-ttl> + +Specifies the maximum amount of time the Cache Manager will cache volume +information retrieved from VL Servers. + +By default, the Cache Manager will cache read-only volume information as long +as a volume callback is held for a read-only volume. The callback may be held +as long as files in the read-only volume are being accessed. The Cache Manager +will cache read/write volume information as long as volume level errors are not +returned from fileservers while accessing files within the volume. + +Use the B<-volume-ttl> to specify the maximum amount of time in seconds +volume information will be cached, regardless of connectivity to the +fileserers. The minimum valid value is 600 seconds (10 minutes). + =back =head1 EXAMPLES diff --git a/src/afs/afs.h b/src/afs/afs.h index bf2273dc9..d94f32825 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -1398,6 +1398,10 @@ extern struct brequest afs_brs[NBRS]; /* request structures */ #define AFS_VOLCHECK_MTPTS 0x4 /* mount point invalidation also */ #define AFS_VOLCHECK_FORCE 0x8 /* do all forcibly */ +/* For volume ttl expiry checks. */ +#define AFS_MIN_VOLUME_TTL 600 +#define AFS_MAX_VOLUME_TTL MAX_AFS_INT32 + #endif /* KERNEL */ #define AFS_FSPORT ((unsigned short) htons(7000)) diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index 3b5641a54..bec71c4d1 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -87,6 +87,8 @@ afs_int32 afs_rx_idledead_rep = AFS_IDLEDEADTIME_REP; static int afscall_set_rxpck_received = 0; +extern afs_int32 afs_volume_ttl; + /* From afs_util.c */ extern afs_int32 afs_md5inum; @@ -1317,6 +1319,13 @@ afs_syscall_call(long parm, long parm2, long parm3, default: code = EINVAL; } + } else if (parm == AFSOP_SET_VOLUME_TTL) { + if ((parm2 < AFS_MIN_VOLUME_TTL) || (parm2 > AFS_MAX_VOLUME_TTL)) { + code = EINVAL; + } else { + afs_volume_ttl = parm2; + code = 0; + } } else { code = EINVAL; } diff --git a/src/afs/afs_volume.c b/src/afs/afs_volume.c index b731a598c..ff7cc4718 100644 --- a/src/afs/afs_volume.c +++ b/src/afs/afs_volume.c @@ -54,6 +54,7 @@ #endif /* vlserver error base define */ /* Exported variables */ +afs_int32 afs_volume_ttl = 0; afs_dcache_id_t volumeInode; /* Inode for VolumeItems file */ afs_rwlock_t afs_xvolume; /** allocation lock for volumes */ struct volume *afs_freeVolList; @@ -415,6 +416,12 @@ afs_ResetVolumes(struct server *srvp, struct volume *tv) * Dynroot volumes are not setup from vldb queries, so never expire. * Read-only volume expiry is tied to the volume callback. * + * Optionally, invalidate volume information after a fixed timeout. + * The vlservers will be periodically probed for volume information. + * This avoids a situation where the vldb information is cached + * indefinitely as long as files in the volume are accessed (and are + * not in the vcache) before the callback expires. + * * \param tv volume to check * \param now current time * @@ -423,8 +430,16 @@ afs_ResetVolumes(struct server *srvp, struct volume *tv) static int IsExpired(struct volume *tv, afs_int32 now) { - return (tv->expireTime < (now + 10)) && (tv->states & VRO) - && !afs_IsDynrootVolume(tv); + if (afs_IsDynrootVolume(tv)) { + return 0; + } + if ((tv->states & VRO) && (tv->expireTime < (now + 10))) { + return 1; + } + if ((afs_volume_ttl != 0) && ((tv->setupTime + afs_volume_ttl) < now)) { + return 1; + } + return 0; } /** diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index 0976099f4..46921728a 100644 --- a/src/afsd/afsd.c +++ b/src/afsd/afsd.c @@ -67,6 +67,7 @@ * -splitcache RW/RO ratio for cache. * -rxmaxfrags Max number of UDP fragments per rx packet. * -inumcalc inode number calculation method; 0=compat, 1=MD5 digest + * -volume-ttl vldb cache timeout in seconds *---------------------------------------------------------------------------*/ #include @@ -284,6 +285,7 @@ int afsd_debug = 0; /*Are we printing debugging info? */ static int afsd_CloseSynch = 0; /*Are closes synchronous or not? */ static int rxmaxmtu = 0; /* Are we forcing a limit on the mtu? */ static int rxmaxfrags = 0; /* Are we forcing a limit on frags? */ +static int volume_ttl = 0; /* enable vldb cache timeout support */ #ifdef AFS_SGI62_ENV #define AFSD_INO_T ino64_t @@ -362,6 +364,7 @@ enum optionsList { OPT_dynrootsparse, OPT_rxmaxfrags, OPT_inumcalc, + OPT_volume_ttl, }; #ifdef MACOS_EVENT_HANDLING @@ -1905,6 +1908,7 @@ CheckOptions(struct cmd_syndesc *as) if (cmd_OptionPresent(as, OPT_inumcalc)) { cmd_OptionAsString(as, OPT_inumcalc, &inumcalc); } + cmd_OptionAsInt(as, OPT_volume_ttl, &volume_ttl); /* parse cacheinfo file if this is a diskcache */ if (ParseCacheInfoFile()) { @@ -2425,6 +2429,14 @@ afsd_run(void) afsd_syscall(AFSOP_ROOTVOLUME, rootVolume); } + if (volume_ttl != 0) { + if (afsd_verbose) + printf("%s: Calling AFSOP_SET_VOLUME_TTL with '%d'\n", rn, volume_ttl); + code = afsd_syscall(AFSOP_SET_VOLUME_TTL, volume_ttl); + if (code != 0) + printf("%s: Error setting volume ttl to %d seconds; code=%d.\n", rn, volume_ttl, code); + } + /* * Pass the kernel the name of the workstation cache file holding the * volume information. @@ -2624,6 +2636,9 @@ afsd_init(void) "send/receive per Rx packet"); cmd_AddParmAtOffset(ts, OPT_inumcalc, "-inumcalc", CMD_SINGLE, CMD_OPTIONAL, "Set inode number calculation method"); + cmd_AddParmAtOffset(ts, OPT_volume_ttl, "-volume-ttl", CMD_SINGLE, + CMD_OPTIONAL, + "Set the vldb cache timeout value in seconds."); } /** @@ -2704,6 +2719,7 @@ afsd_syscall_populate(struct afsd_syscall_args *args, int syscall, va_list ap) case AFSOP_GO: case AFSOP_SET_RMTSYS_FLAG: case AFSOP_SET_INUMCALC: + case AFSOP_SET_VOLUME_TTL: params[0] = CAST_SYSCALL_PARAM((va_arg(ap, int))); break; case AFSOP_SET_THISCELL: diff --git a/src/config/afs_args.h b/src/config/afs_args.h index ee9847274..4fa286ba3 100644 --- a/src/config/afs_args.h +++ b/src/config/afs_args.h @@ -55,6 +55,7 @@ #define AFSOP_SET_RMTSYS_FLAG 44 /* set flag if rmtsys is enabled */ #define AFSOP_SEED_ENTROPY 45 /* Give the kernel hcrypto entropy */ #define AFSOP_SET_INUMCALC 46 /* set inode number calculation method */ +#define AFSOP_SET_VOLUME_TTL 47 /* set the vldb cache timeout */ #define AFSOP_RXLISTENER_DAEMON 48 /* starts kernel RX listener */ -- 2.39.5