#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
#include <sys/types.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
+#include <unistd.h>
#endif
#include <errno.h>
#ifdef AFS_PTHREAD_ENV
/* Forward declarations */
static void * FSYNC_sync(void *);
-static void FSYNC_newconnection(int afd);
-static void FSYNC_com(int fd);
-static void FSYNC_Drop(int fd);
+static void FSYNC_newconnection(osi_socket afd);
+static void FSYNC_com(osi_socket fd);
+static void FSYNC_Drop(osi_socket fd);
static void AcceptOn(void);
static void AcceptOff(void);
static void InitHandler(void);
-static int AddHandler(int fd, void (*aproc)(int));
-static int FindHandler(int afd);
-static int FindHandler_r(int afd);
-static int RemoveHandler(int afd);
+static int AddHandler(osi_socket fd, void (*aproc)(osi_socket));
+static int FindHandler(osi_socket afd);
+static int FindHandler_r(osi_socket afd);
+static int RemoveHandler(osi_socket afd);
#if defined(HAVE_POLL) && defined (AFS_PTHREAD_ENV)
static void CallHandler(struct pollfd *fds, int nfds, int mask);
static void GetHandler(struct pollfd *fds, int maxfds, int events, int *nfds);
#endif
extern int LogLevel;
-static afs_int32 FSYNC_com_VolOp(int fd, SYNC_command * com, SYNC_response * res);
+static afs_int32 FSYNC_com_VolOp(osi_socket fd, SYNC_command * com, SYNC_response * res);
#ifdef AFS_DEMAND_ATTACH_FS
static afs_int32 FSYNC_com_VolError(FSSYNC_VolOp_command * com, SYNC_response * res);
static afs_int32 FSYNC_com_VolOpQuery(FSSYNC_VolOp_command * com, SYNC_response * res);
#endif /* AFS_DEMAND_ATTACH_FS */
-static afs_int32 FSYNC_com_VnQry(int fd, SYNC_command * com, SYNC_response * res);
+static afs_int32 FSYNC_com_VnQry(osi_socket fd, SYNC_command * com, SYNC_response * res);
-static afs_int32 FSYNC_com_StatsOp(int fd, SYNC_command * com, SYNC_response * res);
+static afs_int32 FSYNC_com_StatsOp(osi_socket fd, SYNC_command * com, SYNC_response * res);
static afs_int32 FSYNC_com_StatsOpGeneral(FSSYNC_StatsOp_command * scom, SYNC_response * res);
SYNC_server_state_t * state = &fssync_server_state;
#ifdef AFS_DEMAND_ATTACH_FS
VThreadOptions_t * thread_opts;
-#endif
+ int min_vinit = 2;
+#else
+ /*
+ * For non-DAFS, only wait until we begin attaching volumes (instead
+ * of waiting until all volumes are attached), since it can take
+ * awhile until VInit == 2.
+ */
+ int min_vinit = 1;
+#endif /* AFS_DEMAND_ATTACH_FS */
SYNC_getAddr(&state->endpoint, &state->addr);
SYNC_cleanupSock(state);
MUTEX_ENTER(&rx_stats_mutex); /* protects rxi_pthread_hinum */
tid = ++rxi_pthread_hinum;
MUTEX_EXIT(&rx_stats_mutex);
- pthread_setspecific(rx_thread_id_key, (void *)tid);
+ pthread_setspecific(rx_thread_id_key, (void *)(intptr_t)tid);
Log("Set thread id %d for FSYNC_sync\n", tid);
#endif /* AFS_PTHREAD_ENV */
- while (!VInit) {
- /* Let somebody else run until level > 0. That doesn't mean that
- * all volumes have been attached. */
+ while (VInit < min_vinit) {
+ /* Let somebody else run until all volumes have been preattached
+ * (DAFS), or we have started attaching volumes (non-DAFS). This
+ * doesn't mean that all volumes have been attached.
+ */
#ifdef AFS_PTHREAD_ENV
pthread_yield();
#else /* AFS_PTHREAD_ENV */
}
static void
-FSYNC_newconnection(int afd)
+FSYNC_newconnection(osi_socket afd)
{
#ifdef USE_UNIX_SOCKETS
struct sockaddr_un other;
#else /* USE_UNIX_SOCKETS */
struct sockaddr_in other;
#endif
- int fd;
+ osi_socket fd;
socklen_t junk;
junk = sizeof(other);
fd = accept(afd, (struct sockaddr *)&other, &junk);
/* this function processes commands from an fssync file descriptor (fd) */
afs_int32 FS_cnt = 0;
static void
-FSYNC_com(int fd)
+FSYNC_com(osi_socket fd)
{
SYNC_command com;
SYNC_response res;
if (com.hdr.command == SYNC_COM_CHANNEL_CLOSE) {
res.hdr.response = SYNC_OK;
res.hdr.flags |= SYNC_FLAG_CHANNEL_SHUTDOWN;
- goto respond;
+
+ /* don't respond, just drop; senders of SYNC_COM_CHANNEL_CLOSE
+ * never wait for a response. */
+ goto done;
}
res.hdr.com_seq = com.hdr.com_seq;
respond:
SYNC_putRes(&fssync_server_state, fd, &res);
+
+ done:
if (res.hdr.flags & SYNC_FLAG_CHANNEL_SHUTDOWN) {
FSYNC_Drop(fd);
}
}
static afs_int32
-FSYNC_com_VolOp(int fd, SYNC_command * com, SYNC_response * res)
+FSYNC_com_VolOp(osi_socket fd, SYNC_command * com, SYNC_response * res)
{
int i;
afs_int32 code = SYNC_OK;
FSYNC_com_VolOn(FSSYNC_VolOp_command * vcom, SYNC_response * res)
{
afs_int32 code = SYNC_OK;
+#ifndef AFS_DEMAND_ATTACH_FS
char tvolName[VMAXPATHLEN];
+#endif
Volume * vp;
Error error;
}
#else /* !AFS_DEMAND_ATTACH_FS */
tvolName[0] = '/';
- snprintf(&tvolName[1], sizeof(tvolName)-1, VFORMAT, afs_cast_uint32(vcom->vop->volume));
+ snprintf(&tvolName[1], sizeof(tvolName)-1, VFORMAT, afs_printable_uint32_lu(vcom->vop->volume));
tvolName[sizeof(tvolName)-1] = '\0';
vp = VAttachVolumeByName_r(&error, vcom->vop->partName, tvolName,
Volume * vp;
Error error;
#ifdef AFS_DEMAND_ATTACH_FS
- int reserved = 0;
- Volume *nvp;
+ Volume *nvp, *rvp = NULL;
#endif
if (SYNC_verifyProtocolString(vcom->vop->partName, sizeof(vcom->vop->partName))) {
}
}
+ /* wait for exclusive ops, so we have an accurate picture of the
+ * vol attach state */
+ VCreateReservation_r(vp);
+ VWaitExclusiveState_r(vp);
+ rvp = vp;
+
/* filter based upon requestor
*
* volume utilities are not allowed to check out volumes
/* convert to heavyweight ref */
nvp = VGetVolumeByVp_r(&error, vp);
+ VCancelReservation_r(rvp);
+ rvp = NULL;
if (!nvp) {
+ /*
+ * It's possible for VGetVolumeByVp_r to have dropped and
+ * re-acquired VOL_LOCK, so volume state may have changed
+ * back to one of the states we tested for above. Since
+ * GetVolume can return NULL in some of those states, just
+ * test for the states again here.
+ */
+ switch (V_attachState(vp)) {
+ case VOL_STATE_UNATTACHED:
+ case VOL_STATE_PREATTACHED:
+ case VOL_STATE_SALVAGING:
+ case VOL_STATE_ERROR:
+ /* register the volume operation metadata with the volume
+ *
+ * if the volume is currently pre-attached, attach2()
+ * will evaluate the vol op metadata to determine whether
+ * attaching the volume would be safe */
+ VRegisterVolOp_r(vp, &info);
+ vp->pending_vol_op->vol_op_state = FSSYNC_VolOpRunningUnknown;
+ goto done;
+ default:
+ break;
+ }
+
Log("FSYNC_com_VolOff: failed to get heavyweight reference to volume %u\n",
vcom->vop->volume);
res->hdr.reason = FSYNC_VOL_PKG_ERROR;
vp = NULL;
}
}
+ goto done;
+
+ deny:
+ code = SYNC_DENIED;
done:
+#ifdef AFS_DEMAND_ATTACH_FS
+ if (rvp) {
+ VCancelReservation_r(rvp);
+ }
+#endif
return code;
-
- deny:
- return SYNC_DENIED;
}
/**
} else {
res->hdr.reason = FSYNC_WRONG_PART;
}
+#ifndef AFS_DEMAND_ATTACH_FS
VPutVolume_r(vp);
+#endif /* !AFS_DEMAND_ATTACH_FS */
} else {
res->hdr.reason = FSYNC_UNKNOWN_VOLID;
}
!(V_attachFlags(vp) & VOL_HDR_ATTACHED) ||
!(V_attachFlags(vp) & VOL_HDR_LOADED)) {
res->hdr.reason = FSYNC_HDR_NOT_ATTACHED;
- goto done;
+ goto cleanup;
}
#else /* !AFS_DEMAND_ATTACH_FS */
if (!vp || !vp->header) {
res->hdr.reason = FSYNC_HDR_NOT_ATTACHED;
- goto done;
+ goto cleanup;
}
#endif /* !AFS_DEMAND_ATTACH_FS */
} else {
res->hdr.reason = FSYNC_WRONG_PART;
- goto done;
+ goto cleanup;
}
} else {
res->hdr.reason = FSYNC_UNKNOWN_VOLID;
memcpy(res->payload.buf, &V_disk(vp), sizeof(VolumeDiskData));
res->hdr.response_len += sizeof(VolumeDiskData);
+ code = SYNC_OK;
+
+ cleanup:
#ifndef AFS_DEMAND_ATTACH_FS
VPutVolume_r(vp);
#endif
- code = SYNC_OK;
done:
return code;
#endif /* AFS_DEMAND_ATTACH_FS */
static afs_int32
-FSYNC_com_VnQry(int fd, SYNC_command * com, SYNC_response * res)
+FSYNC_com_VnQry(osi_socket fd, SYNC_command * com, SYNC_response * res)
{
afs_int32 code = SYNC_OK;
FSSYNC_VnQry_hdr * qry = com->payload.buf;
}
static afs_int32
-FSYNC_com_StatsOp(int fd, SYNC_command * com, SYNC_response * res)
+FSYNC_com_StatsOp(osi_socket fd, SYNC_command * com, SYNC_response * res)
{
afs_int32 code = SYNC_OK;
FSSYNC_StatsOp_command scom;
static void
-FSYNC_Drop(int fd)
+FSYNC_Drop(osi_socket fd)
{
struct offlineInfo *p;
int i;
Volume *vp;
tvolName[0] = '/';
- sprintf(&tvolName[1], VFORMAT, afs_cast_uint32(p[i].volumeID));
+ sprintf(&tvolName[1], VFORMAT, afs_printable_uint32_lu(p[i].volumeID));
vp = VAttachVolumeByName_r(&error, p[i].partName, tvolName,
V_VOLUPD);
if (vp)
/* The multiple FD handling code. */
-static int HandlerFD[MAXHANDLERS];
-static void (*HandlerProc[MAXHANDLERS]) (int);
+static osi_socket HandlerFD[MAXHANDLERS];
+static void (*HandlerProc[MAXHANDLERS]) (osi_socket);
static void
InitHandler(void)
#endif
static int
-AddHandler(int afd, void (*aproc) (int))
+AddHandler(osi_socket afd, void (*aproc) (osi_socket))
{
register int i;
ObtainWriteLock(&FSYNC_handler_lock);
}
static int
-FindHandler(register int afd)
+FindHandler(register osi_socket afd)
{
register int i;
ObtainReadLock(&FSYNC_handler_lock);
}
static int
-FindHandler_r(register int afd)
+FindHandler_r(register osi_socket afd)
{
register int i;
for (i = 0; i < MAXHANDLERS; i++)
}
static int
-RemoveHandler(register int afd)
+RemoveHandler(register osi_socket afd)
{
ObtainWriteLock(&FSYNC_handler_lock);
HandlerFD[FindHandler_r(afd)] = -1;
for (i = 0; i < MAXHANDLERS; i++)
if (HandlerFD[i] != -1) {
FD_SET(HandlerFD[i], fdsetp);
- if (maxfd < HandlerFD[i])
+#ifndef AFS_NT40_ENV
+ /* On Windows the nfds parameter to select() is ignored */
+ if (maxfd < HandlerFD[i] || maxfd == (int)-1)
maxfd = HandlerFD[i];
+#endif /* AFS_NT40_ENV */
}
*maxfdp = maxfd;
ReleaseReadLock(&FSYNC_handler_lock); /* just in case */