#include <afsconfig.h>
#include <afs/param.h>
+#include <roken.h>
#include <sys/types.h>
#include <stdio.h>
* fssync server socket handle.
*/
static SYNC_server_state_t fssync_server_state =
- { -1, /* file descriptor */
+ { OSI_NULLSOCKET, /* file descriptor */
FSSYNC_ENDPOINT_DECL, /* server endpoint */
FSYNC_PROTO_VERSION, /* protocol version */
5, /* bind() retry limit */
socklen_t junk;
junk = sizeof(other);
fd = accept(afd, (struct sockaddr *)&other, &junk);
- if (fd == -1) {
+ if (fd == OSI_NULLSOCKET) {
Log("FSYNC_newconnection: accept failed, errno==%d\n", errno);
osi_Assert(1 == 2);
} else if (!AddHandler(fd, FSYNC_com)) {
case FSYNC_VOL_DONE:
case FSYNC_VOL_QUERY:
case FSYNC_VOL_QUERY_HDR:
- case FSYNC_VOL_QUERY_VOP:
#ifdef AFS_DEMAND_ATTACH_FS
+ case FSYNC_VOL_QUERY_VOP:
case FSYNC_VG_QUERY:
case FSYNC_VG_SCAN:
case FSYNC_VG_SCAN_ALL:
/* nothing much to do if we're leaving the volume offline */
#ifdef AFS_DEMAND_ATTACH_FS
if (vp) {
+ VCreateReservation_r(vp);
+ VWaitExclusiveState_r(vp);
+ }
+ if (vp && V_attachState(vp) != VOL_STATE_DELETED) {
if (FSYNC_partMatch(vcom, vp, 1)) {
if ((V_attachState(vp) == VOL_STATE_UNATTACHED) ||
(V_attachState(vp) == VOL_STATE_PREATTACHED)) {
res->hdr.reason = FSYNC_WRONG_PART;
}
} else {
- code = SYNC_DENIED;
+ code = SYNC_FAILED;
res->hdr.reason = FSYNC_UNKNOWN_VOLID;
}
+
+ if (vp) {
+ VCancelReservation_r(vp);
+ vp = NULL;
+ }
#endif
goto done;
}
vcom->vop->partName,
vcom->vop->volume);
if (vp) {
+ VCreateReservation_r(vp);
+ VWaitExclusiveState_r(vp);
VDeregisterVolOp_r(vp);
+ VCancelReservation_r(vp);
+ vp = NULL;
}
#else /* !AFS_DEMAND_ATTACH_FS */
- tvolName[0] = '/';
+ tvolName[0] = OS_DIRSEPC;
snprintf(&tvolName[1], sizeof(tvolName)-1, VFORMAT, afs_printable_uint32_lu(vcom->vop->volume));
tvolName[sizeof(tvolName)-1] = '\0';
if (vp->salvage.requested && !vp->salvage.scheduled) {
vp->salvage.scheduled = 1;
}
+
+ /* If the volume is in VOL_STATE_SALVAGE_REQ, we need to wait
+ * for the vol to go offline before we can give it away. Also
+ * make sure we don't come out with vp in an excl state. */
+ while (V_attachState(vp) == VOL_STATE_SALVAGE_REQ ||
+ VIsExclusiveState(V_attachState(vp))) {
+
+ VOL_CV_WAIT(&V_attachCV(vp));
+ }
+
case debugUtility:
break;
case volumeUtility:
case volumeServer:
- if (V_attachState(vp) == VOL_STATE_SALVAGING ||
- vp->salvage.requested) {
-
+ if (VIsSalvaging(vp)) {
Log("denying offline request for volume %lu; volume is in salvaging state\n",
afs_printable_uint32_lu(vp->hashid));
res->hdr.reason = FSYNC_SALVAGE;
* attaching the volume would be safe */
VRegisterVolOp_r(vp, &info);
vp->pending_vol_op->vol_op_state = FSSYNC_VolOpRunningUnknown;
+ /* fall through */
+
+ case VOL_STATE_DELETED:
goto done;
default:
break;
* attaching the volume would be safe */
VRegisterVolOp_r(vp, &info);
vp->pending_vol_op->vol_op_state = FSSYNC_VolOpRunningUnknown;
+ /* fall through */
+
+ case VOL_STATE_DELETED:
goto done;
default:
break;
}
- Log("FSYNC_com_VolOff: failed to get heavyweight reference to volume %u\n",
- vcom->vop->volume);
+ Log("FSYNC_com_VolOff: failed to get heavyweight reference to volume %u (state=%u, flags=0x%x)\n",
+ vcom->vop->volume, V_attachState(vp), V_attachFlags(vp));
res->hdr.reason = FSYNC_VOL_PKG_ERROR;
goto deny;
} else if (nvp != vp) {
}
#ifdef AFS_DEMAND_ATTACH_FS
+ VCreateReservation_r(vp);
VOfflineForVolOp_r(&error, vp, "A volume utility is running.");
if (error==0) {
osi_Assert(vp->nUsers==0);
vp->pending_vol_op->vol_op_state = FSSYNC_VolOpRunningOffline;
}
else {
+ VWaitExclusiveState_r(vp);
VDeregisterVolOp_r(vp);
code = SYNC_DENIED;
}
+ VCancelReservation_r(vp);
#else
VOffline_r(vp, "A volume utility is running.");
#endif
if (vp) {
if (FSYNC_partMatch(vcom, vp, 1)) {
#ifdef AFS_DEMAND_ATTACH_FS
+ VCreateReservation_r(vp);
+ VWaitExclusiveState_r(vp);
+
if ((V_attachState(vp) == VOL_STATE_UNATTACHED) ||
- (V_attachState(vp) == VOL_STATE_PREATTACHED)) {
+ (V_attachState(vp) == VOL_STATE_PREATTACHED) ||
+ VIsErrorState(V_attachState(vp))) {
/* Change state to DELETED, not UNATTACHED, so clients get
* a VNOVOL error when they try to access from now on. */
VChangeState_r(vp, VOL_STATE_DELETED);
VDeregisterVolOp_r(vp);
+ /* Volume is gone; clear out old salvage stats */
+ memset(&vp->salvage, 0, sizeof(vp->salvage));
+
/* Someday we should free the vp, too, after about 2 hours,
* possibly by putting the vp back on the VLRU. */
code = SYNC_OK;
+ } else if (V_attachState(vp) == VOL_STATE_DELETED) {
+ VDeregisterVolOp_r(vp);
+ res->hdr.reason = FSYNC_UNKNOWN_VOLID;
+
} else {
code = SYNC_DENIED;
res->hdr.reason = FSYNC_BAD_STATE;
}
+
+ VCancelReservation_r(vp);
+ vp = NULL;
#else /* AFS_DEMAND_ATTACH_FS */
if (!vp->specialStatus) {
vp->specialStatus = VNOVOL;
if (FSYNC_partMatch(vcom, vp, 0)) {
/* null out salvsync control state, as it's no longer relevant */
memset(&vp->salvage, 0, sizeof(vp->salvage));
+
+ VCreateReservation_r(vp);
+ VWaitExclusiveState_r(vp);
VDeregisterVolOp_r(vp);
if (vcom->hdr->reason == FSYNC_SALVAGE) {
VChangeState_r(vp, VOL_STATE_ERROR);
}
+ VCancelReservation_r(vp);
+ vp = NULL;
+
code = SYNC_OK;
} else {
res->hdr.reason = FSYNC_WRONG_PART;
vp = VLookupVolume_r(&error, vcom->vop->volume, NULL);
+ if (vp) {
+ VCreateReservation_r(vp);
+ VWaitExclusiveState_r(vp);
+ }
+
if (vp && vp->pending_vol_op) {
- osi_Assert(sizeof(FSSYNC_VolOp_info) <= res->payload.len);
- memcpy(res->payload.buf, vp->pending_vol_op, sizeof(FSSYNC_VolOp_info));
- res->hdr.response_len += sizeof(FSSYNC_VolOp_info);
- } else {
- if (vp) {
- res->hdr.reason = FSYNC_NO_PENDING_VOL_OP;
+ if (!FSYNC_partMatch(vcom, vp, 1)) {
+ res->hdr.reason = FSYNC_WRONG_PART;
+ code = SYNC_FAILED;
} else {
+ osi_Assert(sizeof(FSSYNC_VolOp_info) <= res->payload.len);
+ memcpy(res->payload.buf, vp->pending_vol_op, sizeof(FSSYNC_VolOp_info));
+ res->hdr.response_len += sizeof(FSSYNC_VolOp_info);
+ }
+ } else {
+ if (!vp || V_attachState(vp) == VOL_STATE_DELETED) {
res->hdr.reason = FSYNC_UNKNOWN_VOLID;
+ } else if (!FSYNC_partMatch(vcom, vp, 1)) {
+ res->hdr.reason = FSYNC_WRONG_PART;
+ } else {
+ res->hdr.reason = FSYNC_NO_PENDING_VOL_OP;
}
code = SYNC_FAILED;
}
+
+ if (vp) {
+ VCancelReservation_r(vp);
+ }
return code;
}
Volume *vp;
- tvolName[0] = '/';
+ tvolName[0] = OS_DIRSEPC;
sprintf(&tvolName[1], VFORMAT, afs_printable_uint32_lu(p[i].volumeID));
vp = VAttachVolumeByName_r(&error, p[i].partName, tvolName,
V_VOLUPD);
int i;
ObtainWriteLock(&FSYNC_handler_lock);
for (i = 0; i < MAXHANDLERS; i++) {
- HandlerFD[i] = -1;
+ HandlerFD[i] = OSI_NULLSOCKET;
HandlerProc[i] = 0;
}
ReleaseWriteLock(&FSYNC_handler_lock);
int i;
ObtainWriteLock(&FSYNC_handler_lock);
for (i = 0; i < MAXHANDLERS; i++)
- if (HandlerFD[i] == -1)
+ if (HandlerFD[i] == OSI_NULLSOCKET)
break;
if (i >= MAXHANDLERS) {
ReleaseWriteLock(&FSYNC_handler_lock);
RemoveHandler(osi_socket afd)
{
ObtainWriteLock(&FSYNC_handler_lock);
- HandlerFD[FindHandler_r(afd)] = -1;
+ HandlerFD[FindHandler_r(afd)] = OSI_NULLSOCKET;
ReleaseWriteLock(&FSYNC_handler_lock);
return 1;
}
int fdi = 0;
ObtainReadLock(&FSYNC_handler_lock);
for (i = 0; i < MAXHANDLERS; i++)
- if (HandlerFD[i] != -1) {
+ if (HandlerFD[i] != OSI_NULLSOCKET) {
osi_Assert(fdi<maxfds);
fds[fdi].fd = HandlerFD[i];
fds[fdi].events = events;
FD_ZERO(fdsetp);
ObtainReadLock(&FSYNC_handler_lock); /* just in case */
for (i = 0; i < MAXHANDLERS; i++)
- if (HandlerFD[i] != -1) {
+ if (HandlerFD[i] != OSI_NULLSOCKET) {
FD_SET(HandlerFD[i], fdsetp);
#ifndef AFS_NT40_ENV
/* On Windows the nfds parameter to select() is ignored */