2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
9 * Portions Copyright (c) 2006-2010 Sine Nomine Associates
15 Institution: The Information Technology Center, Carnegie-Mellon University
18 #ifndef AFS_PTHREAD_ENV
19 #define USUAL_PRIORITY (LWP_MAX_PRIORITY - 2)
22 * stack size increased from 8K because the HP machine seemed to have trouble
23 * with the smaller stack
25 #define USUAL_STACK_SIZE (24 * 1024)
26 #endif /* !AFS_PTHREAD_ENV */
30 File server synchronization with external volume utilities.
31 server-side implementation
34 /* This controls the size of an fd_set; it must be defined early before
35 * the system headers define that type and the macros that operate on it.
36 * Its value should be as large as the maximum file descriptor limit we
37 * are likely to run into on any platform. Right now, that is 65536
38 * which is the default hard fd limit on Solaris 9 */
40 #define FD_SETSIZE 65536
43 #include <afsconfig.h>
44 #include <afs/param.h>
49 #ifdef AFS_PTHREAD_ENV
50 # include <opr/lock.h>
52 #include <afs/afsint.h>
53 #include <rx/rx_queue.h>
55 #include <afs/errors.h>
56 #include "daemon_com.h"
57 #include "daemon_com_inline.h"
59 #include "fssync_inline.h"
63 #include <afs/afssyscalls.h>
67 #include "volume_inline.h"
68 #include "partition.h"
74 #endif /* HAVE_POLL */
76 #ifdef USE_UNIX_SOCKETS
78 #include <afs/afsutil.h>
79 #endif /* USE_UNIX_SOCKETS */
81 #ifdef FSSYNC_BUILD_SERVER
83 int (*V_BreakVolumeCallbacks
) (VolumeId volume
);
85 #define MAXHANDLERS 4 /* Up to 4 clients; must be at least 2, so that
86 * move = dump+restore can run on single server */
87 #define MAXOFFLINEVOLUMES 128 /* This needs to be as big as the maximum
88 * number that would be offline for 1 operation.
89 * Current winner is salvage, which needs all
90 * cloned read-only copies offline when salvaging
91 * a single read-write volume */
95 static struct offlineInfo OfflineVolumes
[MAXHANDLERS
][MAXOFFLINEVOLUMES
];
98 * fssync server socket handle.
100 static SYNC_server_state_t fssync_server_state
=
101 { OSI_NULLSOCKET
, /* file descriptor */
102 FSSYNC_ENDPOINT_DECL
, /* server endpoint */
103 FSYNC_PROTO_VERSION
, /* protocol version */
104 5, /* bind() retry limit */
105 100, /* listen() queue depth */
106 "FSSYNC", /* protocol name string */
109 #ifdef AFS_DEMAND_ATTACH_FS
111 * a queue of volume pointers to salvage in the background.
113 struct fsync_salv_node
{
115 Volume
*vp
; /**< volume to salvage */
116 unsigned char update_salv_prio
; /**< whether we should update the salvage priority or not */
119 struct rx_queue head
;
123 static void * FSYNC_salvageThread(void *);
124 static void FSYNC_backgroundSalvage(Volume
*vp
);
125 #endif /* AFS_DEMAND_ATTACH_FS */
127 /* Forward declarations */
128 static void * FSYNC_sync(void *);
129 static void FSYNC_newconnection(osi_socket afd
);
130 static void FSYNC_com(osi_socket fd
);
131 static void FSYNC_Drop(osi_socket fd
);
132 static void AcceptOn(void);
133 static void AcceptOff(void);
134 static void InitHandler(void);
135 static int AddHandler(osi_socket fd
, void (*aproc
)(osi_socket
));
136 static int FindHandler(osi_socket afd
);
137 static int FindHandler_r(osi_socket afd
);
138 static int RemoveHandler(osi_socket afd
);
139 #if defined(HAVE_POLL) && defined (AFS_PTHREAD_ENV)
140 static void CallHandler(struct pollfd
*fds
, int nfds
, int mask
);
141 static void GetHandler(struct pollfd
*fds
, int maxfds
, int events
, int *nfds
);
143 static void CallHandler(fd_set
* fdsetp
);
144 static void GetHandler(fd_set
* fdsetp
, int *maxfdp
);
147 static afs_int32
FSYNC_com_VolOp(osi_socket fd
, SYNC_command
* com
, SYNC_response
* res
);
149 #ifdef AFS_DEMAND_ATTACH_FS
150 static afs_int32
FSYNC_com_VolError(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
152 static afs_int32
FSYNC_com_VolOn(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
153 static afs_int32
FSYNC_com_VolOff(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
154 static afs_int32
FSYNC_com_VolMove(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
155 static afs_int32
FSYNC_com_VolBreakCBKs(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
156 static afs_int32
FSYNC_com_VolDone(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
157 static afs_int32
FSYNC_com_VolQuery(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
158 static afs_int32
FSYNC_com_VolHdrQuery(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
159 #ifdef AFS_DEMAND_ATTACH_FS
160 static afs_int32
FSYNC_com_VGUpdate(osi_socket fd
, SYNC_command
* com
, SYNC_response
* res
);
161 static afs_int32
FSYNC_com_VolOpQuery(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
162 static afs_int32
FSYNC_com_VGQuery(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
163 static afs_int32
FSYNC_com_VGScan(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
164 static afs_int32
FSYNC_com_VGScanAll(FSSYNC_VolOp_command
* com
, SYNC_response
* res
);
165 #endif /* AFS_DEMAND_ATTACH_FS */
167 static afs_int32
FSYNC_com_VnQry(osi_socket fd
, SYNC_command
* com
, SYNC_response
* res
);
169 static afs_int32
FSYNC_com_StatsOp(osi_socket fd
, SYNC_command
* com
, SYNC_response
* res
);
171 static afs_int32
FSYNC_com_StatsOpGeneral(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
);
173 #ifdef AFS_DEMAND_ATTACH_FS
174 static afs_int32
FSYNC_com_StatsOpViceP(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
);
175 static afs_int32
FSYNC_com_StatsOpHash(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
);
176 static afs_int32
FSYNC_com_StatsOpHdr(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
);
177 static afs_int32
FSYNC_com_StatsOpVLRU(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
);
180 static void FSYNC_com_to_info(FSSYNC_VolOp_command
* vcom
, FSSYNC_VolOp_info
* info
);
182 static int FSYNC_partMatch(FSSYNC_VolOp_command
* vcom
, Volume
* vp
, int match_anon
);
186 * This lock controls access to the handler array. The overhead
187 * is minimal in non-preemptive environments.
189 struct Lock FSYNC_handler_lock
;
194 #ifdef AFS_PTHREAD_ENV
196 pthread_attr_t tattr
;
197 #else /* AFS_PTHREAD_ENV */
199 #endif /* AFS_PTHREAD_ENV */
201 Lock_Init(&FSYNC_handler_lock
);
203 #ifdef AFS_PTHREAD_ENV
204 opr_Verify(pthread_attr_init(&tattr
) == 0);
205 opr_Verify(pthread_attr_setdetachstate(&tattr
,
206 PTHREAD_CREATE_DETACHED
) == 0);
207 opr_Verify(pthread_create(&tid
, &tattr
, FSYNC_sync
, NULL
) == 0);
208 #else /* AFS_PTHREAD_ENV */
209 opr_Verify(LWP_CreateProcess(FSYNC_sync
, USUAL_STACK_SIZE
,
210 USUAL_PRIORITY
, NULL
,
211 "FSYNC_sync", &pid
) == LWP_SUCCESS
);
212 #endif /* AFS_PTHREAD_ENV */
214 #ifdef AFS_DEMAND_ATTACH_FS
215 queue_Init(&fsync_salv
.head
);
216 opr_cv_init(&fsync_salv
.cv
);
217 opr_Verify(pthread_create(&tid
, &tattr
, FSYNC_salvageThread
, NULL
) == 0);
218 #endif /* AFS_DEMAND_ATTACH_FS */
221 #if defined(HAVE_POLL) && defined(AFS_PTHREAD_ENV)
222 static struct pollfd FSYNC_readfds
[MAXHANDLERS
];
224 static fd_set FSYNC_readfds
;
229 FSYNC_sync(void * args
)
233 #ifdef AFS_PTHREAD_ENV
236 SYNC_server_state_t
* state
= &fssync_server_state
;
237 #ifdef AFS_DEMAND_ATTACH_FS
238 VThreadOptions_t
* thread_opts
;
242 * For non-DAFS, only wait until we begin attaching volumes (instead
243 * of waiting until all volumes are attached), since it can take
244 * awhile until VInit == 2.
247 #endif /* AFS_DEMAND_ATTACH_FS */
249 /* we must not be called before vol package initialization, since we use
250 * vol package mutexes and conds etc */
253 SYNC_getAddr(&state
->endpoint
, &state
->addr
);
254 SYNC_cleanupSock(state
);
257 (void)signal(SIGPIPE
, SIG_IGN
);
260 #ifdef AFS_PTHREAD_ENV
261 /* set our 'thread-id' so that the host hold table works */
262 tid
= rx_SetThreadNum();
263 Log("Set thread id %d for FSYNC_sync\n", tid
);
264 afs_pthread_setname_self("FSYNC_sync");
265 #endif /* AFS_PTHREAD_ENV */
269 while (VInit
< min_vinit
) {
270 /* Let somebody else run until all volumes have been preattached
271 * (DAFS), or we have started attaching volumes (non-DAFS). This
272 * doesn't mean that all volumes have been attached.
274 #ifdef AFS_PTHREAD_ENV
275 VOL_CV_WAIT(&vol_vinit_cond
);
276 #else /* AFS_PTHREAD_ENV */
277 LWP_DispatchProcess();
278 #endif /* AFS_PTHREAD_ENV */
283 state
->fd
= SYNC_getSock(&state
->endpoint
);
284 code
= SYNC_bindSock(state
);
287 #ifdef AFS_DEMAND_ATTACH_FS
289 * make sure the volume package is incapable of recursively executing
290 * salvsync calls on this thread, since there is a possibility of
293 thread_opts
= malloc(sizeof(VThreadOptions_t
));
294 if (thread_opts
== NULL
) {
295 Log("failed to allocate memory for thread-specific volume package options structure\n");
298 memcpy(thread_opts
, &VThread_defaults
, sizeof(VThread_defaults
));
299 thread_opts
->disallow_salvsync
= 1;
300 opr_Verify(pthread_setspecific(VThread_key
, thread_opts
) == 0);
302 code
= VVGCache_PkgInit();
303 opr_Assert(code
== 0);
310 #if defined(HAVE_POLL) && defined(AFS_PTHREAD_ENV)
312 GetHandler(FSYNC_readfds
, MAXHANDLERS
, POLLIN
|POLLPRI
, &nfds
);
313 if (poll(FSYNC_readfds
, nfds
, -1) >=1)
314 CallHandler(FSYNC_readfds
, nfds
, POLLIN
|POLLPRI
);
317 #ifdef AFS_PTHREAD_ENV
318 struct timeval s_timeout
;
320 GetHandler(&FSYNC_readfds
, &maxfd
);
321 /* Note: check for >= 1 below is essential since IOMGR_select
322 * doesn't have exactly same semantics as select.
324 #ifdef AFS_PTHREAD_ENV
325 s_timeout
.tv_sec
= SYNC_SELECT_TIMEOUT
;
326 s_timeout
.tv_usec
= 0;
327 if (select(maxfd
+ 1, &FSYNC_readfds
, NULL
, NULL
, &s_timeout
) >= 1)
328 #else /* AFS_PTHREAD_ENV */
329 if (IOMGR_Select(maxfd
+ 1, &FSYNC_readfds
, NULL
, NULL
, NULL
) >= 1)
330 #endif /* AFS_PTHREAD_ENV */
331 CallHandler(&FSYNC_readfds
);
334 AFS_UNREACHED(return(NULL
)); /* hush now, little gcc */
337 #ifdef AFS_DEMAND_ATTACH_FS
339 * thread for salvaging volumes in the background.
341 * Since FSSYNC handlers cannot issue SALVSYNC requests in order to avoid
342 * deadlock issues, this thread exists so code in the FSSYNC handler thread
343 * can hand off volumes to be salvaged in the background.
345 * @param[in] args unused
347 * @note DEMAND_ATTACH_FS only
350 FSYNC_salvageThread(void * args
)
353 struct fsync_salv_node
*node
;
358 while (queue_IsEmpty(&fsync_salv
.head
)) {
359 VOL_CV_WAIT(&fsync_salv
.cv
);
362 node
= queue_First(&fsync_salv
.head
, fsync_salv_node
);
366 if (node
->update_salv_prio
) {
367 if (VUpdateSalvagePriority_r(vp
)) {
368 ViceLog(0, ("FSYNC_salvageThread: unable to raise salvage priority "
369 "for volume %" AFS_VOLID_FMT
"\n", afs_printable_VolumeId_lu(vp
->hashid
)));
376 VCancelReservation_r(vp
);
379 AFS_UNREACHED(VOL_UNLOCK
);
380 AFS_UNREACHED(return(NULL
));
384 * salvage a volume in the background.
386 * Salvages cannot be scheduled directly from the main FSYNC thread, so
387 * instead call this function to schedule a salvage asynchronously in the
388 * FSYNC_salvageThread thread.
390 * @param[in] vp volume to pointer to salvage
394 * @note DEMAND_ATTACH_FS only
397 FSYNC_backgroundSalvage(Volume
*vp
)
399 struct fsync_salv_node
*node
;
402 VCreateReservation_r(vp
);
404 node
= malloc(sizeof(struct fsync_salv_node
));
407 /* Save this value, to know if we should VUpdateSalvagePriority_r.
408 * We need to save it here, snce VRequestSalvage_r will change it. */
409 node
->update_salv_prio
= vp
->salvage
.requested
;
411 if (VRequestSalvage_r(&ec
, vp
, SALVSYNC_ERROR
, 0)) {
412 ViceLog(0, ("FSYNC_backgroundSalvage: unable to request salvage for volume %" AFS_VOLID_FMT
"\n",
413 afs_printable_VolumeId_lu(vp
->hashid
)));
416 queue_Append(&fsync_salv
.head
, node
);
417 opr_cv_broadcast(&fsync_salv
.cv
);
419 #endif /* AFS_DEMAND_ATTACH_FS */
422 FSYNC_newconnection(osi_socket afd
)
424 #ifdef USE_UNIX_SOCKETS
425 struct sockaddr_un other
;
426 #else /* USE_UNIX_SOCKETS */
427 struct sockaddr_in other
;
431 junk
= sizeof(other
);
432 fd
= accept(afd
, (struct sockaddr
*)&other
, &junk
);
433 if (fd
== OSI_NULLSOCKET
) {
434 Log("FSYNC_newconnection: accept failed, errno==%d\n", errno
);
436 } else if (!AddHandler(fd
, FSYNC_com
)) {
438 opr_Verify(AddHandler(fd
, FSYNC_com
));
442 /* this function processes commands from an fssync file descriptor (fd) */
443 afs_int32 FS_cnt
= 0;
445 FSYNC_com(osi_socket fd
)
449 SYNC_PROTO_BUF_DECL(com_buf
);
450 SYNC_PROTO_BUF_DECL(res_buf
);
452 memset(&res
.hdr
, 0, sizeof(res
.hdr
));
454 com
.payload
.buf
= (void *)com_buf
;
455 com
.payload
.len
= SYNC_PROTO_MAX_LEN
;
456 res
.hdr
.response_len
= sizeof(res
.hdr
);
457 res
.payload
.len
= SYNC_PROTO_MAX_LEN
;
458 res
.payload
.buf
= (void *)res_buf
;
461 if (SYNC_getCom(&fssync_server_state
, fd
, &com
)) {
462 Log("FSYNC_com: read failed; dropping connection (cnt=%d)\n", FS_cnt
);
467 if (com
.recv_len
< sizeof(com
.hdr
)) {
468 Log("FSSYNC_com: invalid protocol message length (%u)\n", com
.recv_len
);
469 res
.hdr
.response
= SYNC_COM_ERROR
;
470 res
.hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
471 res
.hdr
.flags
|= SYNC_FLAG_CHANNEL_SHUTDOWN
;
475 if (com
.hdr
.proto_version
!= FSYNC_PROTO_VERSION
) {
476 Log("FSYNC_com: invalid protocol version (%u)\n", com
.hdr
.proto_version
);
477 res
.hdr
.response
= SYNC_COM_ERROR
;
478 res
.hdr
.flags
|= SYNC_FLAG_CHANNEL_SHUTDOWN
;
482 if (com
.hdr
.command
== SYNC_COM_CHANNEL_CLOSE
) {
483 res
.hdr
.response
= SYNC_OK
;
484 res
.hdr
.flags
|= SYNC_FLAG_CHANNEL_SHUTDOWN
;
486 /* don't respond, just drop; senders of SYNC_COM_CHANNEL_CLOSE
487 * never wait for a response. */
491 ViceLog(125, ("FSYNC_com: from fd %d got command %ld (%s) reason %ld (%s) "
492 "pt %ld (%s) pid %ld\n", (int)fd
,
493 afs_printable_int32_ld(com
.hdr
.command
),
494 FSYNC_com2string(com
.hdr
.command
),
495 afs_printable_int32_ld(com
.hdr
.reason
),
496 FSYNC_reason2string(com
.hdr
.reason
),
497 afs_printable_int32_ld(com
.hdr
.programType
),
498 VPTypeToString(com
.hdr
.programType
),
499 afs_printable_int32_ld(com
.hdr
.pid
)));
501 res
.hdr
.com_seq
= com
.hdr
.com_seq
;
504 switch (com
.hdr
.command
) {
506 case FSYNC_VOL_ATTACH
:
507 case FSYNC_VOL_LEAVE_OFF
:
509 case FSYNC_VOL_FORCE_ERROR
:
510 case FSYNC_VOL_LISTVOLUMES
:
511 case FSYNC_VOL_NEEDVOLUME
:
513 case FSYNC_VOL_BREAKCBKS
:
515 case FSYNC_VOL_QUERY
:
516 case FSYNC_VOL_QUERY_HDR
:
517 #ifdef AFS_DEMAND_ATTACH_FS
518 case FSYNC_VOL_QUERY_VOP
:
521 case FSYNC_VG_SCAN_ALL
:
523 res
.hdr
.response
= FSYNC_com_VolOp(fd
, &com
, &res
);
525 case FSYNC_VOL_STATS_GENERAL
:
526 case FSYNC_VOL_STATS_VICEP
:
527 case FSYNC_VOL_STATS_HASH
:
528 case FSYNC_VOL_STATS_HDR
:
529 case FSYNC_VOL_STATS_VLRU
:
530 res
.hdr
.response
= FSYNC_com_StatsOp(fd
, &com
, &res
);
532 case FSYNC_VOL_QUERY_VNODE
:
533 res
.hdr
.response
= FSYNC_com_VnQry(fd
, &com
, &res
);
535 #ifdef AFS_DEMAND_ATTACH_FS
538 res
.hdr
.response
= FSYNC_com_VGUpdate(fd
, &com
, &res
);
542 res
.hdr
.response
= SYNC_BAD_COMMAND
;
547 ViceLog(125, ("FSYNC_com: fd %d responding with code %ld (%s) reason %ld "
549 afs_printable_int32_ld(res
.hdr
.response
),
550 SYNC_res2string(res
.hdr
.response
),
551 afs_printable_int32_ld(res
.hdr
.reason
),
552 FSYNC_reason2string(res
.hdr
.reason
)));
555 SYNC_putRes(&fssync_server_state
, fd
, &res
);
558 if (res
.hdr
.flags
& SYNC_FLAG_CHANNEL_SHUTDOWN
) {
564 FSYNC_com_VolOp(osi_socket fd
, SYNC_command
* com
, SYNC_response
* res
)
567 afs_int32 code
= SYNC_OK
;
568 FSSYNC_VolOp_command vcom
;
570 if (com
->recv_len
!= (sizeof(com
->hdr
) + sizeof(FSSYNC_VolOp_hdr
))) {
571 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
572 res
->hdr
.flags
|= SYNC_FLAG_CHANNEL_SHUTDOWN
;
573 return SYNC_COM_ERROR
;
576 vcom
.hdr
= &com
->hdr
;
577 vcom
.vop
= (FSSYNC_VolOp_hdr
*) com
->payload
.buf
;
580 vcom
.volumes
= OfflineVolumes
[FindHandler(fd
)];
581 for (vcom
.v
= NULL
, i
= 0; i
< MAXOFFLINEVOLUMES
; i
++) {
582 if ((vcom
.volumes
[i
].volumeID
== vcom
.vop
->volume
) &&
583 (strncmp(vcom
.volumes
[i
].partName
, vcom
.vop
->partName
,
584 sizeof(vcom
.volumes
[i
].partName
)) == 0)) {
585 vcom
.v
= &vcom
.volumes
[i
];
590 ViceLog(125, ("FSYNC_com_VolOp: fd %d got command for vol %lu part %.16s\n",
591 (int)fd
, afs_printable_uint32_lu(vcom
.vop
->volume
),
592 vcom
.vop
->partName
));
594 switch (com
->hdr
.command
) {
596 case FSYNC_VOL_ATTACH
:
597 case FSYNC_VOL_LEAVE_OFF
:
598 code
= FSYNC_com_VolOn(&vcom
, res
);
601 case FSYNC_VOL_NEEDVOLUME
:
602 code
= FSYNC_com_VolOff(&vcom
, res
);
604 case FSYNC_VOL_LISTVOLUMES
:
608 code
= FSYNC_com_VolMove(&vcom
, res
);
610 case FSYNC_VOL_BREAKCBKS
:
611 code
= FSYNC_com_VolBreakCBKs(&vcom
, res
);
614 code
= FSYNC_com_VolDone(&vcom
, res
);
616 case FSYNC_VOL_QUERY
:
617 code
= FSYNC_com_VolQuery(&vcom
, res
);
619 case FSYNC_VOL_QUERY_HDR
:
620 code
= FSYNC_com_VolHdrQuery(&vcom
, res
);
622 #ifdef AFS_DEMAND_ATTACH_FS
623 case FSYNC_VOL_FORCE_ERROR
:
624 code
= FSYNC_com_VolError(&vcom
, res
);
626 case FSYNC_VOL_QUERY_VOP
:
627 code
= FSYNC_com_VolOpQuery(&vcom
, res
);
630 code
= FSYNC_com_VGQuery(&vcom
, res
);
633 code
= FSYNC_com_VGScan(&vcom
, res
);
635 case FSYNC_VG_SCAN_ALL
:
636 code
= FSYNC_com_VGScanAll(&vcom
, res
);
638 #endif /* AFS_DEMAND_ATTACH_FS */
640 code
= SYNC_BAD_COMMAND
;
647 * service an FSYNC request to bring a volume online.
649 * @param[in] vcom pointer command object
650 * @param[out] res object in which to store response packet
652 * @return operation status
653 * @retval SYNC_OK volume transitioned online
654 * @retval SYNC_FAILED invalid command protocol message
655 * @retval SYNC_DENIED operation could not be completed
657 * @note this is an FSYNC RPC server stub
659 * @note this procedure handles the following FSSYNC command codes:
662 * - FSYNC_VOL_LEAVE_OFF
664 * @note the supplementary reason code contains additional details.
665 * When SYNC_DENIED is returned, the specific reason is
666 * placed in the response packet reason field.
671 FSYNC_com_VolOn(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
673 afs_int32 code
= SYNC_OK
;
674 #ifndef AFS_DEMAND_ATTACH_FS
675 char tvolName
[VMAXPATHLEN
];
680 /* Verify the partition name is null terminated. */
681 if (SYNC_verifyProtocolString(vcom
->vop
->partName
, sizeof(vcom
->vop
->partName
))) {
682 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
687 /* so, we need to attach the volume */
689 #ifdef AFS_DEMAND_ATTACH_FS
690 /* Verify the partition name is not empty. */
691 if (*vcom
->vop
->partName
== 0) {
692 res
->hdr
.reason
= FSYNC_BAD_PART
;
697 /* check DAFS permissions */
698 vp
= VLookupVolume_r(&error
, vcom
->vop
->volume
, NULL
);
700 FSYNC_partMatch(vcom
, vp
, 1) &&
701 vp
->pending_vol_op
&&
702 (vcom
->hdr
->programType
!= vp
->pending_vol_op
->com
.programType
)) {
703 /* a different program has this volume checked out. deny. */
704 Log("FSYNC_VolOn: WARNING: program type %u has attempted to manipulate "
705 "state for volume %" AFS_VOLID_FMT
" using command code %u while the volume is "
706 "checked out by program type %u for command code %u.\n",
707 vcom
->hdr
->programType
,
708 afs_printable_VolumeId_lu(vcom
->vop
->volume
),
710 vp
->pending_vol_op
->com
.programType
,
711 vp
->pending_vol_op
->com
.command
);
713 res
->hdr
.reason
= FSYNC_EXCLUSIVE
;
719 vcom
->v
->volumeID
= 0;
722 if (vcom
->hdr
->command
== FSYNC_VOL_LEAVE_OFF
) {
723 /* nothing much to do if we're leaving the volume offline */
724 #ifdef AFS_DEMAND_ATTACH_FS
726 VCreateReservation_r(vp
);
727 VWaitExclusiveState_r(vp
);
729 if (vp
&& V_attachState(vp
) != VOL_STATE_DELETED
) {
730 if (FSYNC_partMatch(vcom
, vp
, 1)) {
731 if ((V_attachState(vp
) == VOL_STATE_UNATTACHED
) ||
732 (V_attachState(vp
) == VOL_STATE_PREATTACHED
)) {
733 VChangeState_r(vp
, VOL_STATE_UNATTACHED
);
734 VDeregisterVolOp_r(vp
);
737 res
->hdr
.reason
= FSYNC_BAD_STATE
;
741 res
->hdr
.reason
= FSYNC_WRONG_PART
;
745 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
749 VCancelReservation_r(vp
);
756 #ifdef AFS_DEMAND_ATTACH_FS
759 FSYNC_partMatch(vcom
, vp
, 0) &&
760 vp
->pending_vol_op
&&
761 vp
->pending_vol_op
->vol_op_state
== FSSYNC_VolOpRunningOnline
&&
762 V_attachState(vp
) == VOL_STATE_ATTACHED
) {
764 /* noop; the volume stayed online for the volume operation and we were
765 * simply told that the vol op is done. The vp we already have is fine,
766 * so avoid confusing volume routines with trying to preattach an
767 * attached volume. */
770 /* first, check to see whether we have such a volume defined */
771 vp
= VPreAttachVolumeById_r(&error
,
777 VCreateReservation_r(vp
);
778 VWaitExclusiveState_r(vp
);
779 VDeregisterVolOp_r(vp
);
780 VCancelReservation_r(vp
);
783 #else /* !AFS_DEMAND_ATTACH_FS */
784 tvolName
[0] = OS_DIRSEPC
;
785 snprintf(&tvolName
[1], sizeof(tvolName
)-1, VFORMAT
, afs_printable_VolumeId_lu(vcom
->vop
->volume
));
786 tvolName
[sizeof(tvolName
)-1] = '\0';
788 vp
= VAttachVolumeByName_r(&error
, vcom
->vop
->partName
, tvolName
,
792 #endif /* !AFS_DEMAND_ATTACH_FS */
795 res
->hdr
.reason
= error
;
803 * service an FSYNC request to take a volume offline.
805 * @param[in] vcom pointer command object
806 * @param[out] res object in which to store response packet
808 * @return operation status
809 * @retval SYNC_OK volume transitioned offline
810 * @retval SYNC_FAILED invalid command protocol message
811 * @retval SYNC_DENIED operation could not be completed
813 * @note this is an FSYNC RPC server stub
815 * @note this procedure handles the following FSSYNC command codes:
817 * - FSYNC_VOL_NEEDVOLUME
819 * @note the supplementary reason code contains additional details.
820 * When SYNC_DENIED is returned, the specific reason is
821 * placed in the response packet reason field.
826 FSYNC_com_VolOff(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
828 FSSYNC_VolOp_info info
;
829 afs_int32 code
= SYNC_OK
;
833 #ifdef AFS_DEMAND_ATTACH_FS
834 Volume
*nvp
, *rvp
= NULL
;
837 if (SYNC_verifyProtocolString(vcom
->vop
->partName
, sizeof(vcom
->vop
->partName
))) {
838 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
843 /* not already offline, we need to find a slot for newly offline volume */
844 if (vcom
->hdr
->programType
== debugUtility
) {
845 /* debug utilities do not have their operations tracked */
849 for (i
= 0; i
< MAXOFFLINEVOLUMES
; i
++) {
850 if (vcom
->volumes
[i
].volumeID
== 0) {
851 vcom
->v
= &vcom
->volumes
[i
];
861 FSYNC_com_to_info(vcom
, &info
);
863 #ifdef AFS_DEMAND_ATTACH_FS
864 vp
= VLookupVolume_r(&error
, vcom
->vop
->volume
, NULL
);
866 vp
= VGetVolume_r(&error
, vcom
->vop
->volume
);
870 if (!FSYNC_partMatch(vcom
, vp
, 1)) {
871 /* volume on desired partition is not online, so we
872 * should treat this as an offline volume.
874 #ifndef AFS_DEMAND_ATTACH_FS
882 #ifdef AFS_DEMAND_ATTACH_FS
884 ProgramType type
= (ProgramType
) vcom
->hdr
->programType
;
886 /* do initial filtering of requests */
888 /* enforce mutual exclusion for volume ops */
889 if (vp
->pending_vol_op
) {
890 if (vp
->pending_vol_op
->com
.programType
!= type
) {
891 if (vp
->pending_vol_op
->com
.command
== FSYNC_VOL_OFF
&&
892 vp
->pending_vol_op
->com
.reason
== FSYNC_SALVAGE
) {
894 Log("denying offline request for volume %" AFS_VOLID_FMT
"; volume is salvaging\n",
895 afs_printable_VolumeId_lu(vp
->hashid
));
897 res
->hdr
.reason
= FSYNC_SALVAGE
;
900 Log("volume %" AFS_VOLID_FMT
" already checked out\n",
901 afs_printable_VolumeId_lu(vp
->hashid
));
903 Log("vp->vop = { com = { ver=%u, prog=%d, com=%d, reason=%d, len=%u, flags=0x%x }, vop = { vol=%" AFS_VOLID_FMT
", part='%s' } }\n",
904 vp
->pending_vol_op
->com
.proto_version
,
905 vp
->pending_vol_op
->com
.programType
,
906 vp
->pending_vol_op
->com
.command
,
907 vp
->pending_vol_op
->com
.reason
,
908 vp
->pending_vol_op
->com
.command_len
,
909 vp
->pending_vol_op
->com
.flags
,
910 afs_printable_VolumeId_lu(vp
->pending_vol_op
->vop
.volume
),
911 vp
->pending_vol_op
->vop
.partName
);
912 Log("vcom = { com = { ver=%u, prog=%d, com=%d, reason=%d, len=%u, flags=0x%x } , vop = { vol=%" AFS_VOLID_FMT
", part='%s' } }\n",
913 vcom
->hdr
->proto_version
,
914 vcom
->hdr
->programType
,
917 vcom
->hdr
->command_len
,
919 afs_printable_VolumeId_lu(vcom
->vop
->volume
),
920 vcom
->vop
->partName
);
921 res
->hdr
.reason
= FSYNC_EXCLUSIVE
;
924 Log("warning: volume %" AFS_VOLID_FMT
" recursively checked out by programType id %d\n",
925 afs_printable_VolumeId_lu(vp
->hashid
), vcom
->hdr
->programType
);
929 /* wait for exclusive ops, so we have an accurate picture of the
930 * vol attach state */
931 VCreateReservation_r(vp
);
932 VWaitExclusiveState_r(vp
);
935 /* filter based upon requestor
937 * volume utilities / volserver are not allowed to check out
938 * volumes which are in an error state
940 * unknown utility programs will be denied on principal
945 /* it is possible for the salvageserver to checkout a
946 * volume for salvage before its scheduling request
947 * has been sent to the salvageserver */
948 if (vp
->salvage
.requested
&& !vp
->salvage
.scheduled
) {
949 vp
->salvage
.scheduled
= 1;
952 /* If the volume is in VOL_STATE_SALVAGE_REQ, we need to wait
953 * for the vol to go offline before we can give it away. Also
954 * make sure we don't come out with vp in an excl state. */
955 while (V_attachState(vp
) == VOL_STATE_SALVAGE_REQ
||
956 VIsExclusiveState(V_attachState(vp
))) {
958 VOL_CV_WAIT(&V_attachCV(vp
));
966 if (VIsSalvaging(vp
)) {
967 Log("denying offline request for volume %" AFS_VOLID_FMT
"; volume is in salvaging state\n",
968 afs_printable_VolumeId_lu(vp
->hashid
));
969 res
->hdr
.reason
= FSYNC_SALVAGE
;
971 /* the volume hasn't been checked out yet by the salvager,
972 * but we think the volume is salvaging; schedule a
973 * a salvage to update the salvage priority */
974 FSYNC_backgroundSalvage(vp
);
978 if (VIsErrorState(V_attachState(vp
))) {
984 Log("bad program type passed to FSSYNC\n");
988 /* short circuit for offline volume states
989 * so we can avoid I/O penalty of attachment */
990 switch (V_attachState(vp
)) {
991 case VOL_STATE_UNATTACHED
:
992 case VOL_STATE_PREATTACHED
:
993 case VOL_STATE_SALVAGING
:
994 case VOL_STATE_ERROR
:
995 /* register the volume operation metadata with the volume
997 * if the volume is currently pre-attached, attach2()
998 * will evaluate the vol op metadata to determine whether
999 * attaching the volume would be safe */
1000 VRegisterVolOp_r(vp
, &info
);
1001 vp
->pending_vol_op
->vol_op_state
= FSSYNC_VolOpRunningUnknown
;
1004 case VOL_STATE_DELETED
:
1010 /* convert to heavyweight ref */
1011 nvp
= VGetVolumeByVp_r(&error
, vp
);
1014 * It's possible for VGetVolumeByVp_r to have dropped and
1015 * re-acquired VOL_LOCK, so volume state may have changed
1016 * back to one of the states we tested for above. Since
1017 * GetVolume can return NULL in some of those states, just
1018 * test for the states again here.
1020 switch (V_attachState(vp
)) {
1021 case VOL_STATE_UNATTACHED
:
1022 case VOL_STATE_PREATTACHED
:
1023 case VOL_STATE_SALVAGING
:
1024 case VOL_STATE_ERROR
:
1025 /* register the volume operation metadata with the volume
1027 * if the volume is currently pre-attached, attach2()
1028 * will evaluate the vol op metadata to determine whether
1029 * attaching the volume would be safe */
1030 VRegisterVolOp_r(vp
, &info
);
1031 vp
->pending_vol_op
->vol_op_state
= FSSYNC_VolOpRunningUnknown
;
1034 case VOL_STATE_DELETED
:
1040 Log("FSYNC_com_VolOff: failed to get heavyweight reference to volume %" AFS_VOLID_FMT
" (state=%u, flags=0x%x)\n",
1041 afs_printable_VolumeId_lu(vcom
->vop
->volume
),
1042 V_attachState(vp
), V_attachFlags(vp
));
1043 res
->hdr
.reason
= FSYNC_VOL_PKG_ERROR
;
1045 } else if (nvp
!= vp
) {
1046 /* i don't think this should ever happen, but just in case... */
1047 Log("FSYNC_com_VolOff: warning: potentially dangerous race detected\n");
1051 /* kill off lightweight ref to ensure we can't deadlock against ourselves later... */
1052 VCancelReservation_r(rvp
);
1055 /* register the volume operation metadata with the volume */
1056 VRegisterVolOp_r(vp
, &info
);
1059 #endif /* AFS_DEMAND_ATTACH_FS */
1062 if (VVolOpLeaveOnline_r(vp
, &info
)) {
1063 VUpdateVolume_r(&error
, vp
, VOL_UPDATE_WAIT
); /* At least get volume stats right */
1064 if (GetLogLevel() > 0) {
1065 Log("FSYNC: Volume %" AFS_VOLID_FMT
" (%s) was left on line for an external %s request\n",
1066 afs_printable_VolumeId_lu(V_id(vp
)), V_name(vp
),
1067 vcom
->hdr
->reason
== V_CLONE
? "clone" :
1068 vcom
->hdr
->reason
== V_READONLY
? "readonly" :
1069 vcom
->hdr
->reason
== V_DUMP
? "dump" :
1070 vcom
->hdr
->reason
== FSYNC_SALVAGE
? "salvage" :
1073 #ifdef AFS_DEMAND_ATTACH_FS
1074 vp
->pending_vol_op
->vol_op_state
= FSSYNC_VolOpRunningOnline
;
1078 if (VVolOpSetVBusy_r(vp
, &info
)) {
1079 vp
->specialStatus
= VBUSY
;
1082 /* remember what volume we got, so we can keep track of how
1083 * many volumes the volserver or whatever is using. Note that
1084 * vp is valid since leaveonline is only set when vp is valid.
1087 vcom
->v
->volumeID
= vcom
->vop
->volume
;
1088 strlcpy(vcom
->v
->partName
, vp
->partition
->name
, sizeof(vcom
->v
->partName
));
1091 #ifdef AFS_DEMAND_ATTACH_FS
1092 VCreateReservation_r(vp
);
1093 VOfflineForVolOp_r(&error
, vp
, "A volume utility is running.");
1095 opr_Assert(vp
->nUsers
==0);
1096 vp
->pending_vol_op
->vol_op_state
= FSSYNC_VolOpRunningOffline
;
1099 VWaitExclusiveState_r(vp
);
1100 VDeregisterVolOp_r(vp
);
1103 VCancelReservation_r(vp
);
1105 VOffline_r(vp
, "A volume utility is running.");
1116 #ifdef AFS_DEMAND_ATTACH_FS
1118 VCancelReservation_r(rvp
);
1125 * service an FSYNC request to mark a volume as moved.
1127 * @param[in] vcom pointer command object
1128 * @param[out] res object in which to store response packet
1130 * @return operation status
1131 * @retval SYNC_OK volume marked as moved to a remote server
1132 * @retval SYNC_FAILED invalid command protocol message
1133 * @retval SYNC_DENIED current volume state does not permit this operation
1135 * @note this is an FSYNC RPC server stub
1137 * @note this operation also breaks all callbacks for the given volume
1139 * @note this procedure handles the following FSSYNC command codes:
1142 * @note the supplementary reason code contains additional details. For
1143 * instance, SYNC_OK is still returned when the partition specified
1144 * does not match the one registered in the volume object -- reason
1145 * will be FSYNC_WRONG_PART in this case.
1150 FSYNC_com_VolMove(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
1152 afs_int32 code
= SYNC_DENIED
;
1156 if (SYNC_verifyProtocolString(vcom
->vop
->partName
, sizeof(vcom
->vop
->partName
))) {
1157 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1162 /* Yuch: the "reason" for the move is the site it got moved to... */
1163 /* still set specialStatus so we stop sending back VBUSY.
1164 * also should still break callbacks. Note that I don't know
1165 * how to tell if we should break all or not, so we just do it
1166 * since it doesn't matter much if we do an extra break
1167 * volume callbacks on a volume move within the same server */
1168 #ifdef AFS_DEMAND_ATTACH_FS
1169 vp
= VLookupVolume_r(&error
, vcom
->vop
->volume
, NULL
);
1171 vp
= VGetVolume_r(&error
, vcom
->vop
->volume
);
1174 if (FSYNC_partMatch(vcom
, vp
, 1)) {
1175 #ifdef AFS_DEMAND_ATTACH_FS
1176 if ((V_attachState(vp
) == VOL_STATE_UNATTACHED
) ||
1177 (V_attachState(vp
) == VOL_STATE_PREATTACHED
)) {
1180 vp
->specialStatus
= VMOVED
;
1181 #ifdef AFS_DEMAND_ATTACH_FS
1183 res
->hdr
.reason
= FSYNC_BAD_STATE
;
1187 res
->hdr
.reason
= FSYNC_WRONG_PART
;
1189 #ifndef AFS_DEMAND_ATTACH_FS
1191 #endif /* !AFS_DEMAND_ATTACH_FS */
1193 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1196 if ((code
== SYNC_OK
) && (V_BreakVolumeCallbacks
!= NULL
)) {
1197 Log("fssync: volume %" AFS_VOLID_FMT
" moved to %x; breaking all call backs\n",
1198 afs_printable_VolumeId_lu(vcom
->vop
->volume
), vcom
->hdr
->reason
);
1200 (*V_BreakVolumeCallbacks
) (vcom
->vop
->volume
);
1210 * service an FSYNC request to mark a volume as destroyed.
1212 * @param[in] vcom pointer command object
1213 * @param[out] res object in which to store response packet
1215 * @return operation status
1216 * @retval SYNC_OK volume marked as destroyed
1217 * @retval SYNC_FAILED invalid command protocol message
1218 * @retval SYNC_DENIED current volume state does not permit this operation
1220 * @note this is an FSYNC RPC server stub
1222 * @note this procedure handles the following FSSYNC command codes:
1225 * @note the supplementary reason code contains additional details. For
1226 * instance, SYNC_OK is still returned when the partition specified
1227 * does not match the one registered in the volume object -- reason
1228 * will be FSYNC_WRONG_PART in this case.
1233 FSYNC_com_VolDone(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
1235 afs_int32 code
= SYNC_FAILED
;
1239 if (SYNC_verifyProtocolString(vcom
->vop
->partName
, sizeof(vcom
->vop
->partName
))) {
1240 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1244 /* don't try to put online, this call is made only after deleting
1245 * a volume, in which case we want to remove the vol # from the
1246 * OfflineVolumes array only */
1248 vcom
->v
->volumeID
= 0;
1250 vp
= VLookupVolume_r(&error
, vcom
->vop
->volume
, NULL
);
1252 if (FSYNC_partMatch(vcom
, vp
, 1)) {
1253 #ifdef AFS_DEMAND_ATTACH_FS
1254 VCreateReservation_r(vp
);
1255 VWaitExclusiveState_r(vp
);
1257 if ((V_attachState(vp
) == VOL_STATE_UNATTACHED
) ||
1258 (V_attachState(vp
) == VOL_STATE_PREATTACHED
) ||
1259 VIsErrorState(V_attachState(vp
))) {
1261 /* Change state to DELETED, not UNATTACHED, so clients get
1262 * a VNOVOL error when they try to access from now on. */
1264 VChangeState_r(vp
, VOL_STATE_DELETED
);
1265 VDeregisterVolOp_r(vp
);
1267 /* Volume is gone; clear out old salvage stats */
1268 memset(&vp
->salvage
, 0, sizeof(vp
->salvage
));
1270 /* Someday we should free the vp, too, after about 2 hours,
1271 * possibly by putting the vp back on the VLRU. */
1274 } else if (V_attachState(vp
) == VOL_STATE_DELETED
) {
1275 VDeregisterVolOp_r(vp
);
1276 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1280 res
->hdr
.reason
= FSYNC_BAD_STATE
;
1283 VCancelReservation_r(vp
);
1285 #else /* AFS_DEMAND_ATTACH_FS */
1286 if (!vp
->specialStatus
) {
1287 vp
->specialStatus
= VNOVOL
;
1290 #endif /* !AFS_DEMAND_ATTACH_FS */
1292 code
= SYNC_OK
; /* XXX is this really a good idea? */
1293 res
->hdr
.reason
= FSYNC_WRONG_PART
;
1296 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1303 #ifdef AFS_DEMAND_ATTACH_FS
1305 * service an FSYNC request to transition a volume to the hard error state.
1307 * @param[in] vcom pointer command object
1308 * @param[out] res object in which to store response packet
1310 * @return operation status
1311 * @retval SYNC_OK volume transitioned to hard error state
1312 * @retval SYNC_FAILED invalid command protocol message
1313 * @retval SYNC_DENIED (see note)
1315 * @note this is an FSYNC RPC server stub
1317 * @note this procedure handles the following FSSYNC command codes:
1318 * - FSYNC_VOL_FORCE_ERROR
1320 * @note SYNC_DENIED is returned in the following cases:
1321 * - no partition name is specified (reason field set to
1322 * FSYNC_WRONG_PART).
1323 * - volume id not known to fileserver (reason field set
1324 * to FSYNC_UNKNOWN_VOLID).
1326 * @note demand attach fileserver only
1331 FSYNC_com_VolError(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
1335 afs_int32 code
= SYNC_FAILED
;
1337 if (SYNC_verifyProtocolString(vcom
->vop
->partName
, sizeof(vcom
->vop
->partName
))) {
1338 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1342 vp
= VLookupVolume_r(&error
, vcom
->vop
->volume
, NULL
);
1344 if (!vp
&& vcom
->hdr
->reason
== FSYNC_SALVAGE
) {
1345 /* The requested volume doesn't seem to exist. However, it is possible
1346 * that this is triggered by trying to create or clone a volume that
1347 * was prevented from succeeding by a half-created volume in the way.
1348 * (e.g. we tried to create volume X, but volume X exists except that
1349 * its .vol header was deleted for some reason) So, still try to
1350 * a salvage for that volume ID. */
1352 Log("FSYNC_com_VolError: attempting to schedule salvage for unknown "
1353 "volume %lu part %s\n", afs_printable_uint32_lu(vcom
->vop
->volume
),
1354 vcom
->vop
->partName
);
1355 vp
= VPreAttachVolumeById_r(&error
, vcom
->vop
->partName
,
1360 if (FSYNC_partMatch(vcom
, vp
, 0)) {
1361 VCreateReservation_r(vp
);
1362 VWaitExclusiveState_r(vp
);
1363 VDeregisterVolOp_r(vp
);
1365 if (vcom
->hdr
->reason
== FSYNC_SALVAGE
) {
1366 FSYNC_backgroundSalvage(vp
);
1368 /* null out salvsync control state, as it's no longer relevant */
1369 memset(&vp
->salvage
, 0, sizeof(vp
->salvage
));
1370 VChangeState_r(vp
, VOL_STATE_ERROR
);
1373 VCancelReservation_r(vp
);
1378 res
->hdr
.reason
= FSYNC_WRONG_PART
;
1381 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1387 #endif /* AFS_DEMAND_ATTACH_FS */
1390 * service an FSYNC request to break all callbacks for this volume.
1392 * @param[in] vcom pointer command object
1393 * @param[out] res object in which to store response packet
1395 * @return operation status
1396 * @retval SYNC_OK callback breaks scheduled for volume
1398 * @note this is an FSYNC RPC server stub
1400 * @note this procedure handles the following FSSYNC command codes:
1401 * - FSYNC_VOL_BREAKCBKS
1403 * @note demand attach fileserver only
1405 * @todo should do partition matching
1410 FSYNC_com_VolBreakCBKs(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
1412 /* if the volume is being restored, break all callbacks on it */
1413 if (V_BreakVolumeCallbacks
) {
1414 Log("fssync: breaking all call backs for volume %" AFS_VOLID_FMT
"\n",
1415 afs_printable_VolumeId_lu(vcom
->vop
->volume
));
1417 (*V_BreakVolumeCallbacks
) (vcom
->vop
->volume
);
1424 * service an FSYNC request to return the Volume object.
1426 * @param[in] vcom pointer command object
1427 * @param[out] res object in which to store response packet
1429 * @return operation status
1430 * @retval SYNC_OK volume object returned to caller
1431 * @retval SYNC_FAILED bad command packet, or failed to locate volume object
1433 * @note this is an FSYNC RPC server stub
1435 * @note this procedure handles the following FSSYNC command codes:
1441 FSYNC_com_VolQuery(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
1443 afs_int32 code
= SYNC_FAILED
;
1447 if (SYNC_verifyProtocolString(vcom
->vop
->partName
, sizeof(vcom
->vop
->partName
))) {
1448 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1452 #ifdef AFS_DEMAND_ATTACH_FS
1453 vp
= VLookupVolume_r(&error
, vcom
->vop
->volume
, NULL
);
1454 #else /* !AFS_DEMAND_ATTACH_FS */
1455 vp
= VGetVolume_r(&error
, vcom
->vop
->volume
);
1456 #endif /* !AFS_DEMAND_ATTACH_FS */
1459 if (FSYNC_partMatch(vcom
, vp
, 1)) {
1460 if (res
->payload
.len
>= sizeof(Volume
)) {
1461 memcpy(res
->payload
.buf
, vp
, sizeof(Volume
));
1462 res
->hdr
.response_len
+= sizeof(Volume
);
1465 res
->hdr
.reason
= SYNC_REASON_PAYLOAD_TOO_BIG
;
1468 res
->hdr
.reason
= FSYNC_WRONG_PART
;
1470 #ifndef AFS_DEMAND_ATTACH_FS
1474 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1482 * service an FSYNC request to return the Volume header.
1484 * @param[in] vcom pointer command object
1485 * @param[out] res object in which to store response packet
1487 * @return operation status
1488 * @retval SYNC_OK volume header returned to caller
1489 * @retval SYNC_FAILED bad command packet, or failed to locate volume header
1491 * @note this is an FSYNC RPC server stub
1493 * @note this procedure handles the following FSSYNC command codes:
1494 * - FSYNC_VOL_QUERY_HDR
1499 FSYNC_com_VolHdrQuery(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
1501 afs_int32 code
= SYNC_FAILED
;
1505 if (SYNC_verifyProtocolString(vcom
->vop
->partName
, sizeof(vcom
->vop
->partName
))) {
1506 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1509 if (res
->payload
.len
< sizeof(VolumeDiskData
)) {
1510 res
->hdr
.reason
= SYNC_REASON_PAYLOAD_TOO_BIG
;
1514 #ifdef AFS_DEMAND_ATTACH_FS
1515 vp
= VLookupVolume_r(&error
, vcom
->vop
->volume
, NULL
);
1516 #else /* !AFS_DEMAND_ATTACH_FS */
1517 vp
= VGetVolume_r(&error
, vcom
->vop
->volume
);
1521 if (FSYNC_partMatch(vcom
, vp
, 1)) {
1522 #ifdef AFS_DEMAND_ATTACH_FS
1523 if ((vp
->header
== NULL
) ||
1524 !(V_attachFlags(vp
) & VOL_HDR_ATTACHED
) ||
1525 !(V_attachFlags(vp
) & VOL_HDR_LOADED
)) {
1526 res
->hdr
.reason
= FSYNC_HDR_NOT_ATTACHED
;
1529 #else /* !AFS_DEMAND_ATTACH_FS */
1530 if (!vp
|| !vp
->header
) {
1531 res
->hdr
.reason
= FSYNC_HDR_NOT_ATTACHED
;
1534 #endif /* !AFS_DEMAND_ATTACH_FS */
1536 res
->hdr
.reason
= FSYNC_WRONG_PART
;
1540 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1544 memcpy(res
->payload
.buf
, &V_disk(vp
), sizeof(VolumeDiskData
));
1545 res
->hdr
.response_len
+= sizeof(VolumeDiskData
);
1549 #ifndef AFS_DEMAND_ATTACH_FS
1557 #ifdef AFS_DEMAND_ATTACH_FS
1559 FSYNC_com_VolOpQuery(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
1561 afs_int32 code
= SYNC_OK
;
1565 vp
= VLookupVolume_r(&error
, vcom
->vop
->volume
, NULL
);
1568 VCreateReservation_r(vp
);
1569 VWaitExclusiveState_r(vp
);
1572 if (vp
&& vp
->pending_vol_op
) {
1573 if (!FSYNC_partMatch(vcom
, vp
, 1)) {
1574 res
->hdr
.reason
= FSYNC_WRONG_PART
;
1577 opr_Assert(sizeof(FSSYNC_VolOp_info
) <= res
->payload
.len
);
1578 memcpy(res
->payload
.buf
, vp
->pending_vol_op
, sizeof(FSSYNC_VolOp_info
));
1579 res
->hdr
.response_len
+= sizeof(FSSYNC_VolOp_info
);
1582 if (!vp
|| V_attachState(vp
) == VOL_STATE_DELETED
) {
1583 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1584 } else if (!FSYNC_partMatch(vcom
, vp
, 1)) {
1585 res
->hdr
.reason
= FSYNC_WRONG_PART
;
1587 res
->hdr
.reason
= FSYNC_NO_PENDING_VOL_OP
;
1593 VCancelReservation_r(vp
);
1599 FSYNC_com_VGQuery(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
1601 afs_int32 code
= SYNC_FAILED
;
1603 struct DiskPartition64
* dp
;
1605 if (SYNC_verifyProtocolString(vcom
->vop
->partName
, sizeof(vcom
->vop
->partName
))) {
1606 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1610 dp
= VGetPartition_r(vcom
->vop
->partName
, 0);
1612 res
->hdr
.reason
= FSYNC_BAD_PART
;
1616 opr_Assert(sizeof(FSSYNC_VGQry_response_t
) <= res
->payload
.len
);
1618 rc
= VVGCache_query_r(dp
, vcom
->vop
->volume
, res
->payload
.buf
);
1621 res
->hdr
.response_len
+= sizeof(FSSYNC_VGQry_response_t
);
1625 res
->hdr
.reason
= FSYNC_PART_SCANNING
;
1628 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1639 FSYNC_com_VGUpdate(osi_socket fd
, SYNC_command
* com
, SYNC_response
* res
)
1641 afs_int32 code
= SYNC_FAILED
;
1642 struct DiskPartition64
* dp
;
1643 FSSYNC_VGUpdate_command_t
* vgucom
;
1646 if (com
->recv_len
!= (sizeof(com
->hdr
) + sizeof(*vgucom
))) {
1647 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1648 res
->hdr
.flags
|= SYNC_FLAG_CHANNEL_SHUTDOWN
;
1649 code
= SYNC_COM_ERROR
;
1653 vgucom
= com
->payload
.buf
;
1655 ViceLog(125, ("FSYNC_com_VGUpdate: fd %d got command for parent %lu child "
1656 "%lu partName %.16s\n", (int)fd
,
1657 afs_printable_uint32_lu(vgucom
->parent
),
1658 afs_printable_uint32_lu(vgucom
->child
),
1661 if (SYNC_verifyProtocolString(vgucom
->partName
, sizeof(vgucom
->partName
))) {
1662 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1666 dp
= VGetPartition_r(vgucom
->partName
, 0);
1668 res
->hdr
.reason
= FSYNC_BAD_PART
;
1672 switch(com
->hdr
.command
) {
1674 rc
= VVGCache_entry_add_r(dp
, vgucom
->parent
, vgucom
->child
, NULL
);
1678 rc
= VVGCache_entry_del_r(dp
, vgucom
->parent
, vgucom
->child
);
1682 Log("FSYNC_com_VGUpdate called improperly\n");
1687 /* EINVAL means the partition VGC doesn't exist at all; not really
1689 if (rc
== 0 || rc
== EINVAL
) {
1694 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1696 res
->hdr
.reason
= FSYNC_WHATEVER
;
1704 FSYNC_com_VGScan(FSSYNC_VolOp_command
* vcom
, SYNC_response
* res
)
1706 afs_int32 code
= SYNC_FAILED
;
1707 struct DiskPartition64
* dp
;
1709 if (SYNC_verifyProtocolString(vcom
->vop
->partName
, sizeof(vcom
->vop
->partName
))) {
1710 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1714 dp
= VGetPartition_r(vcom
->vop
->partName
, 0);
1716 res
->hdr
.reason
= FSYNC_BAD_PART
;
1720 if (VVGCache_scanStart_r(dp
) == 0) {
1729 FSYNC_com_VGScanAll(FSSYNC_VolOp_command
* com
, SYNC_response
* res
)
1731 afs_int32 code
= SYNC_FAILED
;
1733 if (VVGCache_scanStart_r(NULL
) == 0) {
1739 #endif /* AFS_DEMAND_ATTACH_FS */
1742 FSYNC_com_VnQry(osi_socket fd
, SYNC_command
* com
, SYNC_response
* res
)
1744 afs_int32 code
= SYNC_OK
;
1745 FSSYNC_VnQry_hdr
* qry
= com
->payload
.buf
;
1750 if (com
->recv_len
!= (sizeof(com
->hdr
) + sizeof(FSSYNC_VnQry_hdr
))) {
1751 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1752 res
->hdr
.flags
|= SYNC_FLAG_CHANNEL_SHUTDOWN
;
1753 return SYNC_COM_ERROR
;
1756 ViceLog(125, ("FSYNC_com_VnQry: fd %d got command for vol %lu vnode %lu "
1757 "uniq %lu spare %lu partName %.16s\n", (int)fd
,
1758 afs_printable_uint32_lu(qry
->volume
),
1759 afs_printable_uint32_lu(qry
->vnode
),
1760 afs_printable_uint32_lu(qry
->unique
),
1761 afs_printable_uint32_lu(qry
->spare
),
1764 #ifdef AFS_DEMAND_ATTACH_FS
1765 vp
= VLookupVolume_r(&error
, qry
->volume
, NULL
);
1766 #else /* !AFS_DEMAND_ATTACH_FS */
1767 vp
= VGetVolume_r(&error
, qry
->volume
);
1768 #endif /* !AFS_DEMAND_ATTACH_FS */
1771 res
->hdr
.reason
= FSYNC_UNKNOWN_VOLID
;
1776 vnp
= VLookupVnode(vp
, qry
->vnode
);
1778 res
->hdr
.reason
= FSYNC_UNKNOWN_VNID
;
1783 if (Vn_class(vnp
)->residentSize
> res
->payload
.len
) {
1784 res
->hdr
.reason
= SYNC_REASON_ENCODING_ERROR
;
1789 memcpy(res
->payload
.buf
, vnp
, Vn_class(vnp
)->residentSize
);
1790 res
->hdr
.response_len
+= Vn_class(vnp
)->residentSize
;
1793 #ifndef AFS_DEMAND_ATTACH_FS
1802 FSYNC_com_StatsOp(osi_socket fd
, SYNC_command
* com
, SYNC_response
* res
)
1804 afs_int32 code
= SYNC_OK
;
1805 FSSYNC_StatsOp_command scom
;
1807 if (com
->recv_len
!= (sizeof(com
->hdr
) + sizeof(FSSYNC_StatsOp_hdr
))) {
1808 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1809 res
->hdr
.flags
|= SYNC_FLAG_CHANNEL_SHUTDOWN
;
1810 return SYNC_COM_ERROR
;
1813 scom
.hdr
= &com
->hdr
;
1814 scom
.sop
= (FSSYNC_StatsOp_hdr
*) com
->payload
.buf
;
1817 ViceLog(125, ("FSYNC_com_StatsOp: fd %d got command for stats: "
1818 "{vlru_generation = %lu, hash_bucket = %lu, partName = "
1819 "%.16s}\n", (int)fd
,
1820 afs_printable_uint32_lu(scom
.sop
->args
.vlru_generation
),
1821 afs_printable_uint32_lu(scom
.sop
->args
.hash_bucket
),
1822 scom
.sop
->args
.partName
));
1824 switch (com
->hdr
.command
) {
1825 case FSYNC_VOL_STATS_GENERAL
:
1826 code
= FSYNC_com_StatsOpGeneral(&scom
, res
);
1828 #ifdef AFS_DEMAND_ATTACH_FS
1829 /* statistics for the following subsystems are only tracked
1830 * for demand attach fileservers */
1831 case FSYNC_VOL_STATS_VICEP
:
1832 code
= FSYNC_com_StatsOpViceP(&scom
, res
);
1834 case FSYNC_VOL_STATS_HASH
:
1835 code
= FSYNC_com_StatsOpHash(&scom
, res
);
1837 case FSYNC_VOL_STATS_HDR
:
1838 code
= FSYNC_com_StatsOpHdr(&scom
, res
);
1840 case FSYNC_VOL_STATS_VLRU
:
1841 code
= FSYNC_com_StatsOpVLRU(&scom
, res
);
1843 #endif /* AFS_DEMAND_ATTACH_FS */
1845 code
= SYNC_BAD_COMMAND
;
1852 FSYNC_com_StatsOpGeneral(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
)
1854 afs_int32 code
= SYNC_OK
;
1856 memcpy(res
->payload
.buf
, &VStats
, sizeof(VStats
));
1857 res
->hdr
.response_len
+= sizeof(VStats
);
1862 #ifdef AFS_DEMAND_ATTACH_FS
1864 FSYNC_com_StatsOpViceP(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
)
1866 afs_int32 code
= SYNC_OK
;
1867 struct DiskPartition64
* dp
;
1868 struct DiskPartitionStats64
* stats
;
1870 if (SYNC_verifyProtocolString(scom
->sop
->args
.partName
, sizeof(scom
->sop
->args
.partName
))) {
1871 res
->hdr
.reason
= SYNC_REASON_MALFORMED_PACKET
;
1876 dp
= VGetPartition_r(scom
->sop
->args
.partName
, 0);
1880 stats
= (struct DiskPartitionStats64
*) res
->payload
.buf
;
1881 stats
->free
= dp
->free
;
1882 stats
->totalUsable
= dp
->totalUsable
;
1883 stats
->minFree
= dp
->minFree
;
1884 stats
->f_files
= dp
->f_files
;
1885 stats
->vol_list_len
= dp
->vol_list
.len
;
1887 res
->hdr
.response_len
+= sizeof(struct DiskPartitionStats64
);
1895 FSYNC_com_StatsOpHash(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
)
1897 afs_int32 code
= SYNC_OK
;
1898 struct VolumeHashChainStats
* stats
;
1899 struct VolumeHashChainHead
* head
;
1901 if (scom
->sop
->args
.hash_bucket
>= VolumeHashTable
.Size
) {
1905 head
= &VolumeHashTable
.Table
[scom
->sop
->args
.hash_bucket
];
1906 stats
= (struct VolumeHashChainStats
*) res
->payload
.buf
;
1907 stats
->table_size
= VolumeHashTable
.Size
;
1908 stats
->chain_len
= head
->len
;
1909 stats
->chain_cacheCheck
= head
->cacheCheck
;
1910 stats
->chain_busy
= head
->busy
;
1911 AssignInt64(head
->looks
, &stats
->chain_looks
);
1912 AssignInt64(head
->gets
, &stats
->chain_gets
);
1913 AssignInt64(head
->reorders
, &stats
->chain_reorders
);
1915 res
->hdr
.response_len
+= sizeof(struct VolumeHashChainStats
);
1921 FSYNC_com_StatsOpHdr(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
)
1923 afs_int32 code
= SYNC_OK
;
1925 memcpy(res
->payload
.buf
, &volume_hdr_LRU
.stats
, sizeof(volume_hdr_LRU
.stats
));
1926 res
->hdr
.response_len
+= sizeof(volume_hdr_LRU
.stats
);
1932 FSYNC_com_StatsOpVLRU(FSSYNC_StatsOp_command
* scom
, SYNC_response
* res
)
1934 afs_int32 code
= SYNC_OK
;
1936 code
= SYNC_BAD_COMMAND
;
1940 #endif /* AFS_DEMAND_ATTACH_FS */
1943 * populate an FSSYNC_VolOp_info object from a command packet object.
1945 * @param[in] vcom pointer to command packet
1946 * @param[out] info pointer to info object which will be populated
1948 * @note FSSYNC_VolOp_info objects are attached to Volume objects when
1949 * a volume operation is commenced.
1954 FSYNC_com_to_info(FSSYNC_VolOp_command
* vcom
, FSSYNC_VolOp_info
* info
)
1956 memcpy(&info
->com
, vcom
->hdr
, sizeof(SYNC_command_hdr
));
1957 memcpy(&info
->vop
, vcom
->vop
, sizeof(FSSYNC_VolOp_hdr
));
1958 info
->vol_op_state
= FSSYNC_VolOpPending
;
1962 * check whether command packet partition name matches volume
1963 * object's partition name.
1965 * @param[in] vcom pointer to command packet
1966 * @param[in] vp pointer to volume object
1967 * @param[in] match_anon anon matching control flag (see note below)
1969 * @return whether partitions match
1970 * @retval 0 partitions do NOT match
1971 * @retval 1 partitions match
1973 * @note if match_anon is non-zero, then this function will return a
1974 * positive match for a zero-length partition string in the
1980 FSYNC_partMatch(FSSYNC_VolOp_command
* vcom
, Volume
* vp
, int match_anon
)
1982 return ((match_anon
&& vcom
->vop
->partName
[0] == 0) ||
1983 (strncmp(vcom
->vop
->partName
, V_partition(vp
)->name
,
1984 sizeof(vcom
->vop
->partName
)) == 0));
1989 FSYNC_Drop(osi_socket fd
)
1991 struct offlineInfo
*p
;
1994 #ifndef AFS_DEMAND_ATTACH_FS
1995 char tvolName
[VMAXPATHLEN
];
1999 p
= OfflineVolumes
[FindHandler(fd
)];
2000 for (i
= 0; i
< MAXOFFLINEVOLUMES
; i
++) {
2001 if (p
[i
].volumeID
) {
2004 #ifdef AFS_DEMAND_ATTACH_FS
2005 vp
= VPreAttachVolumeById_r(&error
, p
[i
].partName
, p
[i
].volumeID
);
2007 VCreateReservation_r(vp
);
2008 VWaitExclusiveState_r(vp
);
2009 VDeregisterVolOp_r(vp
);
2010 VCancelReservation_r(vp
);
2013 tvolName
[0] = OS_DIRSEPC
;
2014 sprintf(&tvolName
[1], VFORMAT
, afs_printable_VolumeId_lu(p
[i
].volumeID
));
2015 vp
= VAttachVolumeByName_r(&error
, p
[i
].partName
, tvolName
,
2019 #endif /* !AFS_DEMAND_ATTACH_FS */
2029 static int AcceptHandler
= -1; /* handler id for accept, if turned on */
2034 if (AcceptHandler
== -1) {
2035 opr_Verify(AddHandler(fssync_server_state
.fd
, FSYNC_newconnection
));
2036 AcceptHandler
= FindHandler(fssync_server_state
.fd
);
2043 if (AcceptHandler
!= -1) {
2044 opr_Verify(RemoveHandler(fssync_server_state
.fd
));
2049 /* The multiple FD handling code. */
2051 static osi_socket HandlerFD
[MAXHANDLERS
];
2052 static void (*HandlerProc
[MAXHANDLERS
]) (osi_socket
);
2058 ObtainWriteLock(&FSYNC_handler_lock
);
2059 for (i
= 0; i
< MAXHANDLERS
; i
++) {
2060 HandlerFD
[i
] = OSI_NULLSOCKET
;
2063 ReleaseWriteLock(&FSYNC_handler_lock
);
2066 #if defined(HAVE_POLL) && defined(AFS_PTHREAD_ENV)
2068 CallHandler(struct pollfd
*fds
, int nfds
, int mask
)
2072 ObtainReadLock(&FSYNC_handler_lock
);
2073 for (i
= 0; i
< nfds
; i
++) {
2074 if (fds
[i
].revents
& mask
) {
2075 handler
= FindHandler_r(fds
[i
].fd
);
2076 ReleaseReadLock(&FSYNC_handler_lock
);
2077 (*HandlerProc
[handler
]) (fds
[i
].fd
);
2078 ObtainReadLock(&FSYNC_handler_lock
);
2081 ReleaseReadLock(&FSYNC_handler_lock
);
2085 CallHandler(fd_set
* fdsetp
)
2088 ObtainReadLock(&FSYNC_handler_lock
);
2089 for (i
= 0; i
< MAXHANDLERS
; i
++) {
2090 if (HandlerFD
[i
] >= 0 && FD_ISSET(HandlerFD
[i
], fdsetp
)) {
2091 ReleaseReadLock(&FSYNC_handler_lock
);
2092 (*HandlerProc
[i
]) (HandlerFD
[i
]);
2093 ObtainReadLock(&FSYNC_handler_lock
);
2096 ReleaseReadLock(&FSYNC_handler_lock
);
2101 AddHandler(osi_socket afd
, void (*aproc
) (osi_socket
))
2104 ObtainWriteLock(&FSYNC_handler_lock
);
2105 for (i
= 0; i
< MAXHANDLERS
; i
++)
2106 if (HandlerFD
[i
] == OSI_NULLSOCKET
)
2108 if (i
>= MAXHANDLERS
) {
2109 ReleaseWriteLock(&FSYNC_handler_lock
);
2113 HandlerProc
[i
] = aproc
;
2114 ReleaseWriteLock(&FSYNC_handler_lock
);
2119 FindHandler(osi_socket afd
)
2122 ObtainReadLock(&FSYNC_handler_lock
);
2123 for (i
= 0; i
< MAXHANDLERS
; i
++)
2124 if (HandlerFD
[i
] == afd
) {
2125 ReleaseReadLock(&FSYNC_handler_lock
);
2128 ReleaseReadLock(&FSYNC_handler_lock
); /* just in case */
2130 AFS_UNREACHED(return(-1)); /* satisfy compiler */
2134 FindHandler_r(osi_socket afd
)
2137 for (i
= 0; i
< MAXHANDLERS
; i
++)
2138 if (HandlerFD
[i
] == afd
) {
2142 AFS_UNREACHED(return(-1)); /* satisfy compiler */
2146 RemoveHandler(osi_socket afd
)
2148 ObtainWriteLock(&FSYNC_handler_lock
);
2149 HandlerFD
[FindHandler_r(afd
)] = OSI_NULLSOCKET
;
2150 ReleaseWriteLock(&FSYNC_handler_lock
);
2154 #if defined(HAVE_POLL) && defined(AFS_PTHREAD_ENV)
2156 GetHandler(struct pollfd
*fds
, int maxfds
, int events
, int *nfds
)
2160 ObtainReadLock(&FSYNC_handler_lock
);
2161 for (i
= 0; i
< MAXHANDLERS
; i
++)
2162 if (HandlerFD
[i
] != OSI_NULLSOCKET
) {
2163 opr_Assert(fdi
<maxfds
);
2164 fds
[fdi
].fd
= HandlerFD
[i
];
2165 fds
[fdi
].events
= events
;
2166 fds
[fdi
].revents
= 0;
2170 ReleaseReadLock(&FSYNC_handler_lock
);
2174 GetHandler(fd_set
* fdsetp
, int *maxfdp
)
2179 ObtainReadLock(&FSYNC_handler_lock
); /* just in case */
2180 for (i
= 0; i
< MAXHANDLERS
; i
++)
2181 if (HandlerFD
[i
] != OSI_NULLSOCKET
) {
2182 FD_SET(HandlerFD
[i
], fdsetp
);
2183 #ifndef AFS_NT40_ENV
2184 /* On Windows the nfds parameter to select() is ignored */
2185 if (maxfd
< HandlerFD
[i
] || maxfd
== (int)-1)
2186 maxfd
= HandlerFD
[i
];
2187 #endif /* AFS_NT40_ENV */
2190 ReleaseReadLock(&FSYNC_handler_lock
); /* just in case */
2192 #endif /* HAVE_POLL && AFS_PTHREAD_ENV */
2194 #endif /* FSSYNC_BUILD_SERVER */