unsigned long main_Mod1(void *parm) { long i; for(i=0; i<OSI_MOD1LOOPS; i++) { lock_ObtainMutex(&main_aMutex); osi_Log0(main_logp, "mod1"); lock_ObtainWrite(&main_bRWLock); a -= 52; Sleep(0); b += 52; osi_assert(a+b == 100); Sleep(0); lock_ReleaseWrite(&main_bRWLock); Sleep(0); lock_ReleaseMutex(&main_aMutex); Sleep(0); m1Loops = i; osi_Log1(main_logp, "mod1 done, %d", m1Loops); } lock_ObtainWrite(&main_doneRWLock); done++; Sleep(0); lock_ReleaseWrite(&main_doneRWLock); return 0; }
/* newCellNamep is required to be CELL_MAXNAMELEN in size */ long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl, cm_configProc_t *procp, void *rockp) { int rc; int cellHostAddrs[AFSMAXCELLHOSTS]; char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS]; unsigned short ipRanks[AFSMAXCELLHOSTS]; unsigned short ports[AFSMAXCELLHOSTS]; /* network byte order */ int numServers; int i; struct sockaddr_in vlSockAddr; #ifdef CELLSERV_DEBUG osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep)); #endif /* * Do not perform a DNS lookup if the name is * either a well-known Windows DLL or directory, * or if the name does not contain a top-level * domain, or if the file prefix is the afs pioctl * file name. */ if ( IsWindowsModule(cellNamep) || cm_FsStrChr(cellNamep, '.') == NULL || strncasecmp(cellNamep, CM_IOCTL_FILENAME_NOSLASH, sizeof(CM_IOCTL_FILENAME_NOSLASH)-1) == 0) return -1; rc = getAFSServer("afs3-vlserver", "udp", cellNamep, htons(7003), cellHostAddrs, cellHostNames, ports, ipRanks, &numServers, ttl); if (rc == 0 && numServers > 0) { /* found the cell */ for (i = 0; i < numServers; i++) { memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i], sizeof(long)); vlSockAddr.sin_port = ports[i]; vlSockAddr.sin_family = AF_INET; if (procp) (*procp)(rockp, &vlSockAddr, cellHostNames[i], ipRanks[i]); } if (newCellNamep) { if(FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, cellNamep))) return -1; strlwr(newCellNamep); } return 0; /* found cell */ } else return -1; /* not found */ }
void cm_BkgDaemon(void * parm) { cm_bkgRequest_t *rp; afs_int32 code; char name[32] = ""; long daemonID = (long)parm; snprintf(name, sizeof(name), "cm_BkgDaemon_ShutdownEvent%d", daemonID); cm_BkgDaemon_ShutdownEvent[daemonID] = thrd_CreateEvent(NULL, FALSE, FALSE, name); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", name); rx_StartClientThread(); lock_ObtainWrite(&cm_daemonLock); while (daemon_ShutdownFlag == 0) { if (powerStateSuspended) { Sleep(1000); continue; } if (!cm_bkgListEndp) { osi_SleepW((LONG_PTR)&cm_bkgListp, &cm_daemonLock); lock_ObtainWrite(&cm_daemonLock); continue; } /* we found a request */ for (rp = cm_bkgListEndp; rp; rp = (cm_bkgRequest_t *) osi_QPrev(&rp->q)) { if (cm_ServerAvailable(&rp->scp->fid, rp->userp) && !(rp->scp->flags & CM_SCACHEFLAG_DATASTORING)) break; } if (rp == NULL) { /* we couldn't find a request that we could process at the current time */ lock_ReleaseWrite(&cm_daemonLock); Sleep(1000); lock_ObtainWrite(&cm_daemonLock); continue; } osi_QRemoveHT((osi_queue_t **) &cm_bkgListp, (osi_queue_t **) &cm_bkgListEndp, &rp->q); osi_assertx(cm_bkgQueueCount-- > 0, "cm_bkgQueueCount 0"); lock_ReleaseWrite(&cm_daemonLock); osi_Log1(afsd_logp,"cm_BkgDaemon processing request 0x%p", rp); #ifdef DEBUG_REFCOUNT osi_Log2(afsd_logp,"cm_BkgDaemon (before) scp 0x%x ref %d",rp->scp, rp->scp->refCount); #endif code = (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp); #ifdef DEBUG_REFCOUNT osi_Log2(afsd_logp,"cm_BkgDaemon (after) scp 0x%x ref %d",rp->scp, rp->scp->refCount); #endif /* * Keep the following list synchronized with the * error code list in cm_BkgStore. * cm_SyncOpDone(CM_SCACHESYNC_ASYNCSTORE) will be called there unless * one of these errors has occurred. */ switch ( code ) { case CM_ERROR_TIMEDOUT: /* or server restarting */ case CM_ERROR_RETRY: case CM_ERROR_WOULDBLOCK: case CM_ERROR_ALLBUSY: case CM_ERROR_ALLDOWN: case CM_ERROR_ALLOFFLINE: case CM_ERROR_PARTIALWRITE: if (rp->procp == cm_BkgStore) { osi_Log2(afsd_logp, "cm_BkgDaemon re-queueing failed request 0x%p code 0x%x", rp, code); lock_ObtainWrite(&cm_daemonLock); cm_bkgQueueCount++; osi_QAddT((osi_queue_t **) &cm_bkgListp, (osi_queue_t **)&cm_bkgListEndp, &rp->q); break; } /* otherwise fall through */ case 0: /* success */ default: /* other error */ if (code == 0) osi_Log1(afsd_logp,"cm_BkgDaemon SUCCESS: request 0x%p", rp); else osi_Log2(afsd_logp,"cm_BkgDaemon FAILED: request dropped 0x%p code 0x%x", rp, code); cm_ReleaseUser(rp->userp); cm_ReleaseSCache(rp->scp); free(rp); lock_ObtainWrite(&cm_daemonLock); } } lock_ReleaseWrite(&cm_daemonLock); thrd_SetEvent(cm_BkgDaemon_ShutdownEvent[daemonID]); }
afs_int32 smb_RPCNmpipeTransact(smb_fid_t *fidp, smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { smb_tran2Packet_t *outp = NULL; struct smb_rpc *rpcp; afs_int32 code = 0; cm_user_t * userp = NULL; smb_user_t * uidp = NULL; int len; osi_Log0(smb_logp, "smb_RPCNmpipeTransact() begin"); uidp = smb_FindUID(vcp, p->uid, 0); if (!uidp) return CM_ERROR_BADSMB; userp = smb_GetUserFromUID(uidp); osi_assertx(userp != NULL, "null cm_user_t"); if (uidp && uidp->unp) { osi_Log3(afsd_logp, "RPC Transact uid %d user %x name %S", uidp->userID, userp, osi_LogSaveClientString(afsd_logp, uidp->unp->name)); } else { if (uidp) osi_Log2(afsd_logp, "RPC Transact uid %d user %x no name", uidp->userID, userp); else osi_Log1(afsd_logp, "RPC Transact no uid user %x no name", userp); } lock_ObtainMutex(&fidp->mx); rpcp = fidp->rpcp; code = smb_RPC_BeginOp(rpcp); if (code) { osi_Log0(smb_logp, "Can't begin RPC op. Aborting"); lock_ReleaseMutex(&fidp->mx); smb_ReleaseUID(uidp); cm_ReleaseUser(userp); return code; } osi_assertx((fidp->flags & SMB_FID_RPC), "FID wasn't setup for RPC"); osi_assertx(fidp->rpcp, "smb_rpc_t not associated with RPC FID"); lock_ReleaseMutex(&fidp->mx); code = smb_RPC_PrepareWrite(rpcp); if (code) goto done; code = smb_RPC_WritePacket(rpcp, p->datap, p->totalData, userp); if (code) goto done; code = smb_RPC_PrepareRead(rpcp); if (code) goto done; len = smb_RPC_ReadPacketLength(rpcp, p->maxReturnData); outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, len); if (len > 0) { code = smb_RPC_ReadPacket(rpcp, outp->datap, len); if (code == CM_ERROR_RPC_MOREDATA) { outp->error_code = CM_ERROR_RPC_MOREDATA; } } if (code == 0 || code == CM_ERROR_RPC_MOREDATA) smb_SendTran2Packet(vcp, outp, op); smb_FreeTran2Packet(outp); done: smb_RPC_EndOp(rpcp); osi_Log1(smb_logp, "smb_RPCNmpipeTransact() end code=%d", code); if (uidp) smb_ReleaseUID(uidp); if (userp) cm_ReleaseUser(userp); return code; }
/** Handle SMB_COM_READ_ANDX for an RPC fid Called from smb_ReceiveV3ReadX to handle RPC descriptor reads */ afs_int32 smb_RPCV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { smb_rpc_t *rpcp; long count; afs_int32 code; char *op; cm_user_t *userp; smb_user_t *uidp; count = smb_GetSMBParm(inp, 5); uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); if (!uidp) return CM_ERROR_BADSMB; userp = smb_GetUserFromUID(uidp); osi_assertx(userp != NULL, "null cm_user_t"); osi_Log3(smb_logp, "smb_RPCV3Read for user[0x%p] fid[0x%p (%d)]", userp, fidp, fidp->fid); if (uidp && uidp->unp) { osi_Log3(afsd_logp, "RPC uid %d user %x name %S", uidp->userID, userp, osi_LogSaveClientString(afsd_logp, uidp->unp->name)); } else { if (uidp) osi_Log2(afsd_logp, "RPC uid %d user %x no name", uidp->userID, userp); else osi_Log1(afsd_logp, "RPC no uid user %x no name", userp); } lock_ObtainMutex(&fidp->mx); rpcp = fidp->rpcp; code = smb_RPC_BeginOp(rpcp); lock_ReleaseMutex(&fidp->mx); if (code) { if (uidp) smb_ReleaseUID(uidp); cm_ReleaseUser(userp); return code; } code = smb_RPC_PrepareRead(rpcp); if (uidp) { smb_ReleaseUID(uidp); } if (code) { cm_ReleaseUser(userp); smb_RPC_EndOp(rpcp); return code; } count = smb_RPC_ReadPacketLength(rpcp, count); /* 0 and 1 are reserved for request chaining, were setup by our caller, * and will be further filled in after we return. */ smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */ smb_SetSMBParm(outp, 3, 0); /* resvd */ smb_SetSMBParm(outp, 4, 0); /* resvd */ smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */ /* fill in #6 when we have all the parameters' space reserved */ smb_SetSMBParm(outp, 7, 0); /* resv'd */ smb_SetSMBParm(outp, 8, 0); /* resv'd */ smb_SetSMBParm(outp, 9, 0); /* resv'd */ smb_SetSMBParm(outp, 10, 0); /* resv'd */ smb_SetSMBParm(outp, 11, 0); /* reserved */ /* get op ptr after putting in the last parm, since otherwise we don't * know where the data really is. */ op = smb_GetSMBData(outp, NULL); /* now fill in offset from start of SMB header to first data byte (to op) */ smb_SetSMBParm(outp, 6, ((int) (op - outp->data))); /* set the packet data length the count of the # of bytes */ smb_SetSMBDataLength(outp, count); smb_RPC_ReadPacket(rpcp, op, count); smb_RPC_EndOp(rpcp); /* and cleanup things */ cm_ReleaseUser(userp); return 0; }
afs_int32 smb_RPC_ReadPacket(smb_rpc_t * rpcp, BYTE * buffer, afs_uint32 length) { osi_Log1(smb_logp, " RPC Read Packet for length %d", length); return MSRPC_ReadMessage(&rpcp->rpc_conn, buffer, length); }
/* * lock_ObtainMutex must be held prior to calling * this function. */ afs_int32 cm_RankServer(cm_server_t * tsp) { afs_int32 code = 0; /* start with "success" */ struct rx_debugPeer tpeer; struct rx_peer * rxPeer; afs_uint16 port; afs_uint64 newRank; afs_uint64 perfRank = 0; afs_uint64 rtt = 0; double log_rtt; int isDown = (tsp->flags & CM_SERVERFLAG_DOWN); void *peerRpcStats = NULL; afs_uint64 opcode = 0; switch(tsp->type) { case CM_SERVER_VLDB: port = htons(7003); opcode = opcode_VL_ProbeServer; break; case CM_SERVER_FILE: port = htons(7000); opcode = opcode_RXAFS_GetCapabilities; break; default: return -1; } cm_SetServerIPRank(tsp); if (isDown) { newRank = 0xFFFF; } else { /* * There are three potential components to the ranking: * 1. Any administrative set preference whether it be * via "fs setserverprefs", registry or dns. * * 2. Network subnet mask comparison. * * 3. Performance data. * * If there is an administrative rank, that is the * the primary factor. If not the primary factor * is the network ranking. */ code = rx_GetLocalPeers(tsp->addr.sin_addr.s_addr, port, &tpeer); if (code == 0) { peerRpcStats = rx_CopyPeerRPCStats(opcode, tsp->addr.sin_addr.s_addr, port); if (peerRpcStats == NULL && tsp->type == CM_SERVER_FILE) peerRpcStats = rx_CopyPeerRPCStats(opcode_RXAFS_GetTime, tsp->addr.sin_addr.s_addr, port); if (peerRpcStats) { afs_uint64 execTimeSum = _8THMSEC(RPCOpStat_ExecTimeSum(peerRpcStats)); afs_uint64 queueTimeSum = _8THMSEC(RPCOpStat_QTimeSum(peerRpcStats)); afs_uint64 numCalls = RPCOpStat_NumCalls(peerRpcStats); if (numCalls > 0) rtt = (execTimeSum - queueTimeSum) / numCalls; rx_ReleaseRPCStats(peerRpcStats); } if (rtt == 0 && tpeer.rtt) { /* rtt is ms/8 */ rtt = tpeer.rtt; } if (rtt > 0) { log_rtt = log(rtt); perfRank += (6000 * log_rtt / 5000) * 5000; if (tsp->type == CM_SERVER_FILE) { /* give an edge to servers with high congestion windows */ perfRank -= (tpeer.cwind - 1)* 15; } } } if (tsp->adminRank) { newRank = tsp->adminRank * 0.8; newRank += tsp->ipRank * 0.2; } else { newRank = tsp->ipRank; } if (perfRank) { newRank *= 0.9; newRank += perfRank * 0.1; } newRank += (rand() & 0x000f); /* randomize */ if (newRank > 0xFFFF) osi_Log1(afsd_logp, "new server rank %I64u exceeds 0xFFFF", newRank); /* * If the ranking changes by more than the randomization * factor, update the server reference lists. */ if (abs(newRank - tsp->activeRank) > 0xf) { tsp->activeRank = newRank; lock_ReleaseMutex(&tsp->mx); switch (tsp->type) { case CM_SERVER_FILE: /* * find volumes which might have RO copy * on server and change the ordering of * their RO list */ cm_ChangeRankVolume(tsp); break; case CM_SERVER_VLDB: /* set preferences for an existing vlserver */ cm_ChangeRankCellVLServer(tsp); break; } lock_ObtainMutex(&tsp->mx); } } return code; }