/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ #include #include #include #include #include #include #include #include #include #include "afsd.h" #include #include #include #include #include "cm_rpc.h" #define AFSDIR_CLIENT_ETC_DIRPATH "c:/" #define AFSLOGFILE "afs.log" #define CACHEINFOFILE "cache.info" extern int RXAFSCB_ExecuteRequest(); extern int RXSTATS_ExecuteRequest(); osi_log_t *afsd_logp; char cm_rootVolumeName[64]; DWORD cm_rootVolumeNameLen; cm_volume_t *cm_rootVolumep = NULL; cm_cell_t *cm_rootCellp = NULL; cm_fid_t cm_rootFid; cm_scache_t *cm_rootSCachep; char cm_mountRoot[1024]; DWORD cm_mountRootLen; int cm_logChunkSize; int cm_chunkSize; int afs_diskCacheChunks; char cm_cachePath[128]; int cm_diskCacheEnabled = 0; #ifdef AFS_AFSDB_ENV extern int cm_dnsEnabled; #endif #ifdef AFS_FREELANCE_CLIENT extern int cm_freelanceEnabled; char *cm_FakeRootDir; #endif /* freelance */ int smb_UseV3; int LANadapter; int lanAdaptSet = 0; int rootVolSet = 0; int cacheSetTime = TRUE; int afsd_verbose = 0; int chunkSize; int numBkgD; int numSvThreads; int traceOnPanic = 0; int logReady = 0; char cm_HostName[200]; long cm_HostAddr; /*char cm_CachePath[200];*/ /*DWORD cm_CachePathLen;*/ char cm_CacheInfoPath[1024]; int cacheBlocks; int sawCacheSize=0, sawDiskCacheSize=0, sawMountRoot=0; int sawCacheBaseDir=0; char cm_AFSLogFile[200]; int afsd_CloseSynch = 0; int afs_shutdown = 0; char cm_confDir[200]; BOOL isGateway = FALSE; BOOL reportSessionStartups = FALSE; int afsd_debug; cm_initparams_v1 cm_initParams; /* * AFSD Initialization Log * * This is distinct from the regular debug logging facility. * Log items go directly to a file, not to an array in memory, so that even * if AFSD crashes, the log can be inspected. */ FILE *afsi_file; void afsi_start() { char wd[100]; char t[100], u[100]; int zilch; int code; time_t now; char *p; afsi_file = NULL; /*code = GetWindowsDirectory(wd, sizeof(wd)); if (code == 0) return;*/ strcpy (wd, "C:"); strcat(wd, "\\afsd_init.log"); /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/ time (&now); strcpy(t, asctime(localtime(&now))); /*afsi_file = CreateFile(wd, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);*/ /*afsi_file = open(wd, O_RDWR | O_CREAT | O_RSHARE);*/ afsi_file = fopen(wd, "wt"); setbuf(afsi_file, NULL); /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, u, sizeof(u));*/ time (&now); strcpy(u, asctime(localtime(&now))); p = strchr(u, '\n'); if (p) *p = 0; p = strchr(u, '\r'); if (p) *p = 0; strcat(t, ": Create log file\n"); strcat(u, ": Created log file\n"); /*WriteFile(afsi_file, t, strlen(t), &zilch, NULL); WriteFile(afsi_file, u, strlen(u), &zilch, NULL);*/ /*write(afsi_file, t, strlen(t)); write(afsi_file, u, strlen(u));*/ fputs(t, afsi_file); fputs(u, afsi_file); } void afsi_log(char *pattern, ...) { char s[100], t[100], u[100]; int zilch; time_t now; va_list ap; #ifndef DEBUG return; #endif va_start(ap, pattern); vsprintf(s, pattern, ap); /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/ time(&now); strcpy(t, asctime(localtime(&now))); sprintf(u, "%s: %s\n", t, s); if (afsi_file != NULL) /* fputs(u, stderr); */ fputs(u, afsi_file); /*write(afsi_file, u, strlen(u));*/ /*WriteFile(afsi_file, u, strlen(u), &zilch, NULL);*/ } /* * Standard AFSD trace */ void afsd_ForceTrace(BOOL flush) { FILE *handle; int len; char buf[100]; if (!logReady) return; /*len = GetTempPath(99, buf);*/ /*strcpy(&buf[len], "/afsd.log");*/ strcpy(buf, "c:/afsd.log"); /*handle = CreateFile(buf, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);*/ /*handle = open(buf, O_RDWR | O_CREAT | O_RSHARE);*/ handle = fopen(buf, "wt"); if (handle == NULL) { logReady = 0; osi_panic("Cannot create log file", __FILE__, __LINE__); } osi_LogPrint(afsd_logp, handle); if (flush) fflush(handle); /*FlushFileBuffers(handle);*/ /*CloseHandle(handle);*/ fclose(handle); } /*------------------------------------------------------------------------------ * ParseCacheInfoFile * * Description: * Open the file containing the description of the workstation's AFS cache * and pull out its contents. The format of this file is as follows: * * cm_mountRoot:cacheBaseDir:cacheBlocks * * Arguments: * None. * * Returns: * 0 if everything went well, * 1 otherwise. * * Environment: * Nothing interesting. * * Side Effects: * Sets globals. *---------------------------------------------------------------------------*/ int ParseCacheInfoFile() { static char rn[]="ParseCacheInfoFile"; /*This routine's name*/ FILE *cachefd; /*Descriptor for cache info file*/ int parseResult; /*Result of our fscanf()*/ int32 tCacheBlocks; char tCacheBaseDir[1024], *tbd, tCacheMountDir[1024], *tmd; /*char cacheBaseDir[1024]; /* cache in mem, this is ignored */ if (afsd_debug) printf("%s: Opening cache info file '%s'...\n", rn, cm_CacheInfoPath); cachefd = fopen(cm_CacheInfoPath, "r"); if (!cachefd) { printf("%s: Can't read cache info file '%s'\n", rn, cm_CacheInfoPath); return(1); } /* * Parse the contents of the cache info file. All chars up to the first * colon are the AFS mount directory, all chars to the next colon are the * full path name of the workstation cache directory and all remaining chars * represent the number of blocks in the cache. */ tCacheMountDir[0] = tCacheBaseDir[0] = '\0'; parseResult = fscanf(cachefd, "%1024[^;];%1024[^;];%d", tCacheMountDir, tCacheBaseDir, &tCacheBlocks); /* * Regardless of how the parse went, we close the cache info file. */ fclose(cachefd); if (parseResult == EOF || parseResult < 3) { printf("%s: Format error in cache info file!\n", rn); if (parseResult == EOF) printf("\tEOF encountered before any field parsed.\n"); else printf("\t%d out of 3 fields successfully parsed.\n", parseResult); printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n", cm_mountRoot, cm_cachePath, cacheBlocks); return(1); } for (tmd = tCacheMountDir; *tmd == '\n' || *tmd == ' ' || *tmd == '\t'; tmd++) ; for (tbd = tCacheBaseDir; *tbd == '\n' || *tbd == ' ' || *tbd == '\t'; tbd++) ; /* now copy in the fields not explicitly overridden by cmd args */ if (!sawMountRoot) { strcpy(cm_mountRoot, tmd); cm_mountRootLen = strlen(tmd); } if (!sawCacheBaseDir) strcpy(cm_cachePath, tbd); if (!sawCacheSize) cacheBlocks = tCacheBlocks; if (afsd_debug) { printf("%s: Cache info file successfully parsed:\n", rn); printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n", tmd, tbd, tCacheBlocks); } /*printf("cm_cachePath: %s\n", cm_cachePath);*/ /*PartSizeOverflow(tbd, cacheBlocks);*/ return(0); } /* * AFSD Initialization */ int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock) { osi_uid_t debugID; long cacheBlocks; long cacheSize; long logChunkSize; long stats; long traceBufSize; long ltt, ltto; char rootCellName[256]; struct rx_service *serverp; static struct rx_securityClass *nullServerSecurityClassp; struct hostent *thp; char *msgBuf; char buf[200]; DWORD dummyLen; long code; struct cmd_syndesc *ts; char *afsconf_path; long diskCacheSize; /*WSADATA WSAjunk; WSAStartup(0x0101, &WSAjunk);*/ #ifndef DJGPP /* setup osidebug server at RPC slot 1000 */ osi_LongToUID(1000, &debugID); code = osi_InitDebug(&debugID); afsi_log("osi_InitDebug code %d", code); // osi_LockTypeSetDefault("stat"); /* comment this out for speed * if (code != 0) { *reasonP = "unknown error"; return -1; } #endif /* who are we ? */ gethostname(cm_HostName, sizeof(cm_HostName)); #ifdef DJGPP /* For some reason, we may be getting space-padded hostnames. If so, we take out the padding so that we can append -AFS later. */ { char *space = strchr(cm_HostName,' '); if (space) *space = '\0'; } #endif afsi_log("gethostname %s", cm_HostName); thp = gethostbyname(cm_HostName); memcpy(&cm_HostAddr, thp->h_addr_list[0], 4); /* seed random number generator */ srand(ntohl(cm_HostAddr)); /* Get configuration parameters from command line */ /* call atoi on the appropriate parsed results */ if (!as->parms[20].items) { /* -startup */ fprintf(stderr, "Please do not run this program directly. Use the AFS Client Windows loader\nto start AFS.\n"); exit(1); } if (as->parms[0].items) { /* -lanadapt */ LANadapter = atoi(as->parms[0].items->data); lanAdaptSet = 1; afsi_log("LAN adapter number %d", LANadapter); } else { LANadapter = -1; afsi_log("Default LAN adapter number"); } if (as->parms[1].items) { /* -threads */ numSvThreads = atoi(as->parms[1].items->data); afsi_log("%d server threads", numSvThreads); } else { numSvThreads = CM_CONFIGDEFAULT_SVTHREADS; afsi_log("Defaulting to %d server threads", numSvThreads); } if (as->parms[2].items) { /* -rootvol */ strcpy(cm_rootVolumeName, as->parms[2].items->data); rootVolSet = 1; afsi_log("Root volume %s", cm_rootVolumeName); } else { strcpy(cm_rootVolumeName, "root.afs"); afsi_log("Default root volume name root.afs"); } if (as->parms[3].items) { /* -stat */ stats = atoi(as->parms[3].items->data); afsi_log("Status cache size %d", stats); } else { stats = CM_CONFIGDEFAULT_STATS; afsi_log("Default status cache size %d", stats); } if (as->parms[4].items) { /* -memcache */ /* no-op */ } if (as->parms[5].items) { /* -cachedir */ /* no-op; cache is in memory, not mapped file */ strcpy(cm_cachePath, as->parms[5].items->data); sawCacheBaseDir = 1; } if (as->parms[6].items) { /* -mountdir */ strcpy(cm_mountRoot, as->parms[6].items->data); cm_mountRootLen = strlen(cm_mountRoot); sawMountRoot = 1; afsi_log("Mount root %s", cm_mountRoot); } else { strcpy(cm_mountRoot, "/afs"); cm_mountRootLen = 4; /* Don't log */ } if (as->parms[7].items) { /* -daemons */ numBkgD = atoi(as->parms[7].items->data); afsi_log("%d background daemons", numBkgD); } else { numBkgD = CM_CONFIGDEFAULT_DAEMONS; afsi_log("Defaulting to %d background daemons", numBkgD); } if (as->parms[8].items) { /* -nosettime */ cacheSetTime = FALSE; } if (as->parms[9].items) { /* -verbose */ afsd_verbose = 1; } if (as->parms[10].items) { /* -debug */ afsd_debug = 1; afsd_verbose = 1; } if (as->parms[11].items) { /* -chunksize */ chunkSize = atoi(as->parms[11].items->data); if (chunkSize < 12 || chunkSize > 30) { afsi_log("Invalid chunk size %d, using default", logChunkSize); logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE; } } else { logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE; afsi_log("Default chunk size %d", logChunkSize); } cm_logChunkSize = logChunkSize; cm_chunkSize = 1 << logChunkSize; if (as->parms[12].items) { /* -dcache */ cacheSize = atoi(as->parms[12].items->data); afsi_log("Cache size %d", cacheSize); sawCacheSize = 1; } else { cacheSize = CM_CONFIGDEFAULT_CACHESIZE; afsi_log("Default cache size %d", cacheSize); } afsconf_path = getenv("AFSCONF"); if (!afsconf_path) strcpy(cm_confDir, AFSDIR_CLIENT_ETC_DIRPATH); else strcpy(cm_confDir, afsconf_path); if (as->parms[13].items) { /* -confdir */ strcpy(cm_confDir, as->parms[13].items->data); } sprintf(cm_CacheInfoPath, "%s/%s", cm_confDir, CACHEINFOFILE); sprintf(cm_AFSLogFile, "%s/%s", cm_confDir, AFSLOGFILE); if (as->parms[14].items) { /* -logfile */ strcpy(cm_AFSLogFile, as->parms[14].items->data); } if (as->parms[15].items) { /* -waitclose */ afsd_CloseSynch = 1; } if (as->parms[16].items) { /* -shutdown */ afs_shutdown = 1; /* * Cold shutdown is the default */ printf("afsd: Shutting down all afs processes and afs state\n"); /*call_syscall(AFSOP_SHUTDOWN, 1);*/ exit(0); } if (as->parms[17].items) { /* -sysname */ strcpy(cm_sysName, as->parms[17].items->data); } else strcpy(cm_sysName, "i386_win95"); if (as->parms[18].items) { /* -gateway */ isGateway = 1; afsi_log("Set for %s service", isGateway ? "gateway" : "stand-alone"); } else isGateway = 0; if (as->parms[19].items) { /* -tracebuf */ traceBufSize = atoi(as->parms[19].items->data); afsi_log("Trace Buffer size %d", traceBufSize); } else { traceBufSize = CM_CONFIGDEFAULT_TRACEBUFSIZE; afsi_log("Default trace buffer size %d", traceBufSize); } if (as->parms[21].items) { /* -diskcache */ diskCacheSize = atoi(as->parms[21].items->data); cm_diskCacheEnabled = 1; afsi_log("Disk cache size %d K", diskCacheSize); /*printf("Disk cache size %d K", diskCacheSize);*/ sawDiskCacheSize = 1; } else { diskCacheSize = 50000; /*CM_CONFIGDEFAULT_DISKCACHESIZE;*/ afsi_log("Default disk cache size %d", diskCacheSize); } if (as->parms[22].items) { /* -noafsdb */ cm_dnsEnabled = 0; } if (as->parms[23].items) { /* -freelance */ cm_freelanceEnabled = 1; } if (ParseCacheInfoFile()) { exit(1); } /* setup early variables */ /* These both used to be configurable. */ smb_UseV3 = 1; buf_bufferSize = CM_CONFIGDEFAULT_BLOCKSIZE; /* turn from 1024 byte units into memory blocks */ cacheBlocks = (cacheSize * 1024) / buf_bufferSize; afs_diskCacheChunks = (diskCacheSize * 1024) / buf_bufferSize; /*printf("afs_diskCacheChunks=%d\n", afs_diskCacheChunks);*/ /* * Save client configuration for GetCacheConfig requests */ cm_initParams.nChunkFiles = 0; cm_initParams.nStatCaches = stats; cm_initParams.nDataCaches = 0; cm_initParams.nVolumeCaches = 0; cm_initParams.firstChunkSize = cm_chunkSize; cm_initParams.otherChunkSize = cm_chunkSize; cm_initParams.cacheSize = cacheSize; cm_initParams.setTime = 0; cm_initParams.memCache = 0; /* setup and enable debug log */ afsd_logp = osi_LogCreate("afsd", traceBufSize); afsi_log("osi_LogCreate log addr %x", afsd_logp); osi_LogEnable(afsd_logp); logReady = 1; #if 0 /* get network related info */ cm_noIPAddr = CM_MAXINTERFACE_ADDR; code = syscfg_GetIFInfo(&cm_noIPAddr, cm_IPAddr, cm_SubnetMask, cm_NetMtu, cm_NetFlags); if ( (cm_noIPAddr <= 0) || (code <= 0 ) ) afsi_log("syscfg_GetIFInfo error code %d", code); else afsi_log("First Network address %x SubnetMask %x", cm_IPAddr[0], cm_SubnetMask[0]); #endif /* initialize RX, and tell it to listen to port 7001, which is used for * callback RPC messages. */ code = rx_Init(htons(7001)); afsi_log("rx_Init code %x", code); if (code != 0) { *reasonP = "afsd: failed to init rx client on port 7001"; return -1; } /* Initialize the RPC server for session keys */ /*RpcInit();*/ /* create an unauthenticated service #1 for callbacks */ nullServerSecurityClassp = rxnull_NewServerSecurityObject(); serverp = rx_NewService(0, 1, "AFS", &nullServerSecurityClassp, 1, RXAFSCB_ExecuteRequest); afsi_log("rx_NewService addr %x", serverp); if (serverp == NULL) { *reasonP = "unknown error"; return -1; } nullServerSecurityClassp = rxnull_NewServerSecurityObject(); serverp = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", &nullServerSecurityClassp, 1, RXSTATS_ExecuteRequest); afsi_log("rx_NewService addr %x", serverp); if (serverp == NULL) { *reasonP = "unknown error"; return -1; } /* start server threads, *not* donating this one to the pool */ rx_StartServer(0); afsi_log("rx_StartServer"); #ifdef AFS_AFSDB_ENV /* initialize dns lookup */ if (cm_InitDNS(cm_dnsEnabled) == -1) cm_dnsEnabled = 0; /* init failed, so deactivate */ afsi_log("cm_InitDNS %d", cm_dnsEnabled); #endif /* init user daemon, and other packages */ cm_InitUser(); cm_InitACLCache(2*stats); cm_InitConn(); cm_InitCell(); cm_InitServer(); cm_InitVolume(); cm_InitIoctl(); smb_InitIoctl(); cm_InitCallback(); cm_InitSCache(stats); code = cm_InitDCache(0, cacheBlocks); afsi_log("cm_InitDCache code %x", code); if (code != 0) { *reasonP = "error initializing cache"; return -1; } code = cm_GetRootCellName(rootCellName); afsi_log("cm_GetRootCellName code %d rcn %s", code, (code ? "" : rootCellName)); if (code != 0 && !cm_freelanceEnabled) { *reasonP = "can't find root cell name in ThisCell"; return -1; } else if (cm_freelanceEnabled) cm_rootCellp = NULL; if (code == 0 && !cm_freelanceEnabled) { cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE); afsi_log("cm_GetCell addr %x", cm_rootCellp); if (cm_rootCellp == NULL) { *reasonP = "can't find root cell in CellServDB"; return -1; } } #ifdef AFS_FREELANCE_CLIENT if (cm_freelanceEnabled) cm_InitFreelance(); #endif return 0; } int afsd_InitDaemons(char **reasonP) { long code; cm_req_t req; cm_InitReq(&req); /* this should really be in an init daemon from here on down */ if (!cm_freelanceEnabled) { code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp, &req, CM_FLAG_CREATE, &cm_rootVolumep); afsi_log("cm_GetVolumeByName code %x root vol %x", code, (code ? 0xffffffff : cm_rootVolumep)); if (code != 0) { *reasonP = "can't find root volume in root cell"; return -1; } } /* compute the root fid */ if (!cm_freelanceEnabled) { cm_rootFid.cell = cm_rootCellp->cellID; cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep); cm_rootFid.vnode = 1; cm_rootFid.unique = 1; } else cm_FakeRootFid(&cm_rootFid); code = cm_GetSCache(&cm_rootFid, &cm_rootSCachep, cm_rootUserp, &req); afsi_log("cm_GetSCache code %x scache %x", code, (code ? 0xffffffff : cm_rootSCachep)); if (code != 0) { *reasonP = "unknown error"; return -1; } cm_InitDaemon(numBkgD); afsi_log("cm_InitDaemon"); return 0; } int afsd_InitSMB(char **reasonP) { char hostName[200]; char *ctemp; /* Do this last so that we don't handle requests before init is done. * Here we initialize the SMB listener. */ strcpy(hostName, cm_HostName); ctemp = strchr(hostName, '.'); /* turn ntdfs.* into ntdfs */ if (ctemp) *ctemp = 0; hostName[11] = 0; /* ensure that even after adding the -A, we * leave one byte free for the netbios server * type. */ strcat(hostName, "-AFS"); strupr(hostName); smb_Init(afsd_logp, hostName, smb_UseV3, LANadapter, numSvThreads); afsi_log("smb_Init"); return 0; }