#include <afsconfig.h>
#include <afs/param.h>
-
-#include <sys/types.h>
-#include <stdio.h>
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#include <time.h>
-#else
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-#include <errno.h>
-#include <afs/afs_assert.h>
-#include <signal.h>
-#include <string.h>
+#include <roken.h>
#include <rx/xdr.h>
#include <afs/afsint.h>
#ifdef AFS_PTHREAD_ENV
/* set our 'thread-id' so that the host hold table works */
- tid = rx_NewThreadId();
- pthread_setspecific(rx_thread_id_key, (void *)(intptr_t)tid);
+ tid = rx_SetThreadNum();
Log("Set thread id %d for FSYNC_sync\n", tid);
+ afs_pthread_setname_self("FSYNC_sync");
#endif /* AFS_PTHREAD_ENV */
VOL_LOCK;
CallHandler(FSYNC_readfds, nfds, POLLIN|POLLPRI);
#else
int maxfd;
+#ifdef AFS_PTHREAD_ENV
+ struct timeval s_timeout;
+#endif
GetHandler(&FSYNC_readfds, &maxfd);
/* Note: check for >= 1 below is essential since IOMGR_select
* doesn't have exactly same semantics as select.
*/
#ifdef AFS_PTHREAD_ENV
- if (select(maxfd + 1, &FSYNC_readfds, NULL, NULL, NULL) >= 1)
+ s_timeout.tv_sec = SYNC_SELECT_TIMEOUT;
+ s_timeout.tv_usec = 0;
+ if (select(maxfd + 1, &FSYNC_readfds, NULL, NULL, &s_timeout) >= 1)
#else /* AFS_PTHREAD_ENV */
if (IOMGR_Select(maxfd + 1, &FSYNC_readfds, NULL, NULL, NULL) >= 1)
#endif /* AFS_PTHREAD_ENV */
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:
Volume * vp;
Error error;
+ /* Verify the partition name is null terminated. */
if (SYNC_verifyProtocolString(vcom->vop->partName, sizeof(vcom->vop->partName))) {
res->hdr.reason = SYNC_REASON_MALFORMED_PACKET;
code = SYNC_FAILED;
/* so, we need to attach the volume */
#ifdef AFS_DEMAND_ATTACH_FS
+ /* Verify the partition name is not empty. */
+ if (*vcom->vop->partName == 0) {
+ res->hdr.reason = FSYNC_BAD_PART;
+ code = SYNC_FAILED;
+ goto done;
+ }
+
/* check DAFS permissions */
vp = VLookupVolume_r(&error, vcom->vop->volume, NULL);
if (vp &&
/* 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;
}
#ifdef AFS_DEMAND_ATTACH_FS
- /* first, check to see whether we have such a volume defined */
- vp = VPreAttachVolumeById_r(&error,
- vcom->vop->partName,
- vcom->vop->volume);
+
+ if (vp &&
+ FSYNC_partMatch(vcom, vp, 0) &&
+ vp->pending_vol_op &&
+ vp->pending_vol_op->vol_op_state == FSSYNC_VolOpRunningOnline &&
+ V_attachState(vp) == VOL_STATE_ATTACHED) {
+
+ /* noop; the volume stayed online for the volume operation and we were
+ * simply told that the vol op is done. The vp we already have is fine,
+ * so avoid confusing volume routines with trying to preattach an
+ * attached volume. */
+
+ } else {
+ /* first, check to see whether we have such a volume defined */
+ vp = VPreAttachVolumeById_r(&error,
+ 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';
V_VOLUPD);
if (vp)
VPutVolume_r(vp);
+#endif /* !AFS_DEMAND_ATTACH_FS */
if (error) {
code = SYNC_DENIED;
res->hdr.reason = error;
}
-#endif /* !AFS_DEMAND_ATTACH_FS */
done:
return code;
*/
switch (type) {
case salvageServer:
+ case volumeSalvager:
/* it is possible for the salvageserver to checkout a
* volume for salvage before its scheduling request
* has been sent to the salvageserver */
case VOL_STATE_PREATTACHED:
case VOL_STATE_SALVAGING:
case VOL_STATE_ERROR:
- case VOL_STATE_DELETED:
/* register the volume operation metadata with the volume
*
* if the volume is currently pre-attached, attach2()
* 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;
case VOL_STATE_PREATTACHED:
case VOL_STATE_SALVAGING:
case VOL_STATE_ERROR:
- case VOL_STATE_DELETED:
/* register the volume operation metadata with the volume
*
* if the volume is currently pre-attached, attach2()
* 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 (vp) {
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) {
FSYNC_backgroundSalvage(vp);
} else {
+ /* null out salvsync control state, as it's no longer relevant */
+ memset(&vp->salvage, 0, sizeof(vp->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);
}
VOL_UNLOCK;
RemoveHandler(fd);
-#ifdef AFS_NT40_ENV
- closesocket(fd);
-#else
- close(fd);
-#endif
+ rk_closesocket(fd);
AcceptOn();
}