vol: detach offline volumes on dafs 15/12515/4
authorMarcio Barbosa <mbarbosa@sinenomine.net>
Tue, 31 Jan 2017 14:43:18 +0000 (11:43 -0300)
committerBenjamin Kaduk <kaduk@mit.edu>
Sun, 12 Mar 2017 03:27:53 +0000 (22:27 -0500)
Taking a volume offline always clears the inService bit. Taking a
volume out of service also takes it offline. Therefore, if the
inService flag is false, the volume in question should be offline.
On dafs, an offline volume should be unattached.

The attach2() function does not change the state of the volume received
as an argument to unattached when the inService flag is false. Instead,
this function changes the state of the volume in question to
pre-attached and returns VNOVOL to the client. As result, subsequent
accesses to this volume will make the server try and fail to attach
this offline volume over and over again, writing to the FileLog each
time.

To fix this problem, detach the volume received as an argument if the
inService flag is false. Since the new state of this volume will be
unattached, subsequent accesses will not hit attach2().

This situation where a volume is not offline but is also not in service
can occur if a volume is taken offline with vos offline and some time
later the DAFS fileserver is shutdown and restarted; the volume is
placed into the preattach state by default when the server restarts.
Each access to the volume by clients then causes the fileserver to
attempt to attach the volume, which fails, since the in-service flag in
the volume header is false from the previous vos offline.  The
fileserver will log a warning to the FileLog on each attempt to attach
the volume, and this will fill the FileLog with duplicate messages
corresponding to the number of attempted accesses.

Change-Id: Ifce07c83c1e8dbf250b88b847d331234bdaa9df5
Reviewed-on: https://gerrit.openafs.org/12515
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/vol/volume.c

index 202bdcc..f1ff10a 100644 (file)
@@ -3471,6 +3471,9 @@ attach2(Error * ec, VolumeId volumeId, char *path, struct DiskPartition64 *partp
                FreeVolumeHeader(vp);
            } else if (!V_inService(vp)) {
                Log("Volume %lu offline: not in service\n", afs_printable_uint32_lu(V_id(vp)));
+               /* the volume is offline and should be unattached */
+               *ec = VOFFLINE;
+               error_state = VOL_STATE_UNATTACHED;
                FreeVolumeHeader(vp);
            } else {
                Log("Volume %lu offline: needs salvage\n", afs_printable_uint32_lu(V_id(vp)));