Prevents any portion of the fileserver binary from being paged (swapped)
out of memory on a file server machine running the IRIX operating system.
This option is not supported on platforms other than IRIX.
+
+=item B<-offline-timeout> <I<timeout in seconds>>
+
+Setting this option to I<N> means that if any clients are reading from a
+volume when we want to offline that volume (for example, as part of
+releasing a volume), we will wait I<N> seconds for the clients' request
+to finish. If the clients' requests have not finished, we will then
+interrupt the client requests and send an error to those clients,
+allowing the volume to go offline.
+
+If a client is interrupted, from the client's point of view, it will
+appear as if they had accessed the volume after it had gone offline. For
+RO volumes, this mean the client should fail-over to other valid RO
+sites for that volume. This option may speed up volume releases if
+volumes are being accessed by clients that have slow or unreliable
+network connections.
+
+Setting this option to C<0> means to interrupt clients immediately if a
+volume is waiting to go offline. Setting this option to C<-1> means to
+wait forever for client requests to finish. The default value is C<-1>.
+
+For the LWP fileserver, the only valid value for this option is C<-1>.
+
+=item B<-offline-shutdown-timeout> <I<timeout in seconds>>
+
+This option behaves similarly to B<-offline-timeout> but applies to
+volumes that are going offline as part of the fileserver shutdown
+process. If the value specified is I<N>, we will interrupt any clients
+reading from volumes after I<N> seconds have passed since we first
+needed to wait for a volume to offline during the shutdown process.
+
+Setting this option to C<0> means to interrupt all clients reading from
+volumes immediately during the shutdown process. Setting this option to
+C<-1> means to wait forever for client requests to finish during the
+shutdown process.
+
+If B<-offline-timeout> is specified, the default value of
+B<-offline-shutdown-timeout> is the value specified for
+B<-offline-timeout>. Otherwise, the default value is C<-1>.
+
+For the LWP fileserver, the only valid value for this option is C<-1>.
* are incremented and they must be eventualy released.
*/
static afs_int32
-CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
+CheckVnodeWithCall(AFSFid * fid, Volume ** volptr, struct VCallByVol *cbv,
+ Vnode ** vptr, int lock)
{
Error fileCode = 0;
Error local_errorCode, errorCode = -1;
#endif
errorCode = 0;
- *volptr = VGetVolumeTimed(&local_errorCode, &errorCode, (afs_int32) fid->Volume, ts);
+ *volptr = VGetVolumeWithCall(&local_errorCode, &errorCode,
+ fid->Volume, ts, cbv);
if (!errorCode) {
osi_Assert(*volptr);
break;
return (0);
} /*CheckVnode */
+static_inline afs_int32
+CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
+{
+ return CheckVnodeWithCall(fid, volptr, NULL, vptr, lock);
+}
+
/*
* This routine returns the ACL associated with the targetptr. If the
* targetptr isn't a directory, we access its parent dir and get the ACL
* interface calls.
*/
static afs_int32
-GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
- Vnode ** targetptr, int chkforDir, Vnode ** parent,
- struct client **client, int locktype, afs_int32 * rights,
- afs_int32 * anyrights)
+GetVolumePackageWithCall(struct rx_connection *tcon, struct VCallByVol *cbv,
+ AFSFid * Fid, Volume ** volptr, Vnode ** targetptr,
+ int chkforDir, Vnode ** parent, struct client **client,
+ int locktype, afs_int32 * rights, afs_int32 * anyrights)
{
struct acl_accessList *aCL; /* Internal access List */
int aCLSize; /* size of the access list */
Error errorCode = 0; /* return code to caller */
- if ((errorCode = CheckVnode(Fid, volptr, targetptr, locktype)))
+ if ((errorCode = CheckVnodeWithCall(Fid, volptr, cbv, targetptr, locktype)))
return (errorCode);
if (chkforDir) {
if (chkforDir == MustNOTBeDIR
} /*GetVolumePackage */
+static_inline afs_int32
+GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
+ Vnode ** targetptr, int chkforDir, Vnode ** parent,
+ struct client **client, int locktype, afs_int32 * rights,
+ afs_int32 * anyrights)
+{
+ return GetVolumePackageWithCall(tcon, NULL, Fid, volptr, targetptr,
+ chkforDir, parent, client, locktype,
+ rights, anyrights);
+}
+
/*
* This is the opposite of GetVolumePackage(), and is always used at the end of
* AFS calls to put back all used vnodes and the volume in the proper order!
*/
static void
-PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
- Vnode * parentptr, Volume * volptr, struct client **client)
+PutVolumePackageWithCall(Vnode * parentwhentargetnotdir, Vnode * targetptr,
+ Vnode * parentptr, Volume * volptr,
+ struct client **client, struct VCallByVol *cbv)
{
Error fileCode = 0; /* Error code returned by the volume package */
osi_Assert(!fileCode || (fileCode == VSALVAGE));
}
if (volptr) {
- VPutVolume(volptr);
+ VPutVolumeWithCall(volptr, cbv);
}
if (*client) {
PutClient(client);
}
} /*PutVolumePackage */
+static_inline void
+PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
+ Vnode * parentptr, Volume * volptr, struct client **client)
+{
+ PutVolumePackageWithCall(parentwhentargetnotdir, targetptr, parentptr,
+ volptr, client, NULL);
+}
+
static int
VolumeOwner(struct client *client, Vnode * targetptr)
{
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client = NULL; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
+ struct VCallByVol tcbv, *cbv = NULL;
#if FS_STATS_DETAILED
struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
struct fs_stats_xferData *xferP; /* Ptr to this op's byte size struct */
("SRXAFS_FetchData, Fid = %u.%u.%u, Host %s:%d, Id %d\n",
Fid->Volume, Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),
ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+
+ queue_NodeInit(&tcbv);
+ tcbv.call = acall;
+ cbv = &tcbv;
+
/*
* Get volume/vnode for the fetched file; caller's access rights to
* it are also returned
*/
if ((errorCode =
- GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK,
+ GetVolumePackageWithCall(tcon, cbv, Fid, &volptr, &targetptr, DONTCHECK,
&parentwhentargetnotdir, &client, READ_LOCK,
&rights, &anyrights)))
goto Bad_FetchData;
Bad_FetchData:
/* Update and store volume/vnode and parent vnodes back */
- (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr, &client);
+ (void)PutVolumePackageWithCall(parentwhentargetnotdir, targetptr,
+ (Vnode *) 0, volptr, &client, cbv);
ViceLog(2, ("SRXAFS_FetchData returns %d\n", errorCode));
errorCode = CallPostamble(tcon, errorCode, thost);
(*a_bytesFetchedP) += nBytes;
#endif /* FS_STATS_DETAILED */
if (nBytes != wlen) {
+ afs_int32 err;
FDH_CLOSE(fdP);
#ifndef HAVE_PIOV
FreeSendBuffer((struct afs_buffer *)tbuffer);
#endif /* HAVE_PIOV */
+ err = VIsGoingOffline(volptr);
+ if (err) {
+ return err;
+ }
return -31;
}
Len -= wlen;
int sendBufSize = 16384; /* send buffer size */
int saneacls = 0; /* Sane ACLs Flag */
static int unsafe_attach = 0; /* avoid inUse check on vol attach? */
+static int offline_timeout = -1; /* -offline-timeout option */
+static int offline_shutdown_timeout = -1; /* -offline-shutdown-timeout option */
struct timeval tp;
fputs("[-abortthreshold <abort threshold>] ", stdout);
fputs("[-nojumbo (disable jumbogram network packets - deprecated)] ", stdout);
fputs("[-jumbo (enable jumbogram network packets)] ", stdout);
+ fputs("[-offline-timeout <client RX timeout for offlining volumes>]", stdout);
+ fputs("[-offline-shutdown-timeout <RX timeout for offlining volumes during shutdown>]", stdout);
/* fputs("[-enable_peer_stats] ", stdout); */
/* fputs("[-enable_process_stats] ", stdout); */
fputs("[-help]\n", stdout);
else if (strcmp(argv[i], "-saneacls") == 0) {
saneacls = 1;
}
+ else if (strcmp(argv[i], "-offline-timeout") == 0) {
+ if (i + 1 >= argc) {
+ printf("You have to specify -offline-timeout <integer>\n");
+ return -1;
+ }
+ offline_timeout = atoi(argv[++i]);
+#ifndef AFS_PTHREAD_ENV
+ if (offline_timeout != -1) {
+ printf("The only valid -offline-timeout value for the LWP "
+ "fileserver is -1\n");
+ return -1;
+ }
+#endif /* AFS_PTHREAD_ENV */
+ if (offline_timeout < -1) {
+ printf("Invalid -offline-timeout value %s; the only valid "
+ "negative value is -1\n", argv[i]);
+ return -1;
+ }
+ }
+ else if (strcmp(argv[i], "-offline-shutdown-timeout") == 0) {
+ if (i + 1 >= argc) {
+ printf("You have to specify -offline-shutdown-timeout "
+ "<integer>\n");
+ return -1;
+ }
+ offline_shutdown_timeout = atoi(argv[++i]);
+#ifndef AFS_PTHREAD_ENV
+ if (offline_shutdown_timeout != -1) {
+ printf("The only valid -offline-shutdown-timeout value for the "
+ "LWP fileserver is -1\n");
+ return -1;
+ }
+#endif /* AFS_PTHREAD_ENV */
+ if (offline_shutdown_timeout < -1) {
+ printf("Invalid -offline-timeout value %s; the only valid "
+ "negative value is -1\n", argv[i]);
+ return -1;
+ }
+ }
else {
return (-1);
}
opts.nSmallVnodes = nSmallVns;
opts.volcache = volcache;
opts.unsafe_attach = unsafe_attach;
+ if (offline_timeout != -1) {
+ opts.interrupt_rxcall = rx_InterruptCall;
+ opts.offline_timeout = offline_timeout;
+ }
+ if (offline_shutdown_timeout == -1) {
+ /* default to -offline-timeout, if shutdown-specific timeout is not
+ * specified */
+ opts.offline_shutdown_timeout = offline_timeout;
+ } else {
+ opts.interrupt_rxcall = rx_InterruptCall;
+ opts.offline_shutdown_timeout = offline_shutdown_timeout;
+ }
if (VInitVolumePackage2(fileServer, &opts)) {
ViceLog(0,