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
10 #include <afs/param.h>
12 #include <afs/afs_args.h>
23 #include <rx/rx_null.h>
28 #define AFSDIR_CLIENT_ETC_DIRPATH "c:/"
29 #define AFSLOGFILE "afs.log"
30 #define CACHEINFOFILE "cache.info"
32 extern int RXAFSCB_ExecuteRequest();
33 extern int RXSTATS_ExecuteRequest();
37 char cm_rootVolumeName[64];
38 DWORD cm_rootVolumeNameLen;
39 cm_volume_t *cm_rootVolumep = NULL;
40 cm_cell_t *cm_rootCellp = NULL;
42 cm_scache_t *cm_rootSCachep;
43 char cm_mountRoot[1024];
44 DWORD cm_mountRootLen;
47 int afs_diskCacheChunks;
48 char cm_cachePath[128];
49 int cm_diskCacheEnabled = 0;
51 extern int cm_dnsEnabled;
54 #ifdef AFS_FREELANCE_CLIENT
55 extern int cm_freelanceEnabled;
57 #endif /* freelance */
64 int cacheSetTime = TRUE;
75 char cm_HostName[200];
78 /*char cm_CachePath[200];*/
79 /*DWORD cm_CachePathLen;*/
80 char cm_CacheInfoPath[1024];
82 int sawCacheSize=0, sawDiskCacheSize=0, sawMountRoot=0;
83 int sawCacheBaseDir=0;
84 char cm_AFSLogFile[200];
85 int afsd_CloseSynch = 0;
89 BOOL isGateway = FALSE;
90 BOOL reportSessionStartups = FALSE;
93 cm_initparams_v1 cm_initParams;
97 * AFSD Initialization Log
99 * This is distinct from the regular debug logging facility.
100 * Log items go directly to a file, not to an array in memory, so that even
101 * if AFSD crashes, the log can be inspected.
117 /*code = GetWindowsDirectory(wd, sizeof(wd));
118 if (code == 0) return;*/
120 strcat(wd, "\\afsd_init.log");
121 /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/
123 strcpy(t, asctime(localtime(&now)));
124 /*afsi_file = CreateFile(wd, GENERIC_WRITE, FILE_SHARE_READ, NULL,
125 CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);*/
126 /*afsi_file = open(wd, O_RDWR | O_CREAT | O_RSHARE);*/
127 afsi_file = fopen(wd, "wt");
128 setbuf(afsi_file, NULL);
130 /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, u, sizeof(u));*/
132 strcpy(u, asctime(localtime(&now)));
133 p = strchr(u, '\n'); if (p) *p = 0;
134 p = strchr(u, '\r'); if (p) *p = 0;
135 strcat(t, ": Create log file\n");
136 strcat(u, ": Created log file\n");
137 /*WriteFile(afsi_file, t, strlen(t), &zilch, NULL);
138 WriteFile(afsi_file, u, strlen(u), &zilch, NULL);*/
139 /*write(afsi_file, t, strlen(t));
140 write(afsi_file, u, strlen(u));*/
146 afsi_log(char *pattern, ...)
148 char s[100], t[100], u[100];
155 va_start(ap, pattern);
157 vsprintf(s, pattern, ap);
158 /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/
160 strcpy(t, asctime(localtime(&now)));
161 sprintf(u, "%s: %s\n", t, s);
162 if (afsi_file != NULL)
163 /* fputs(u, stderr); */
165 /*write(afsi_file, u, strlen(u));*/
166 /*WriteFile(afsi_file, u, strlen(u), &zilch, NULL);*/
170 * Standard AFSD trace
173 void afsd_ForceTrace(BOOL flush)
179 if (!logReady) return;
181 /*len = GetTempPath(99, buf);*/
182 /*strcpy(&buf[len], "/afsd.log");*/
183 strcpy(buf, "c:/afsd.log");
184 /*handle = CreateFile(buf, GENERIC_WRITE, FILE_SHARE_READ,
185 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);*/
186 /*handle = open(buf, O_RDWR | O_CREAT | O_RSHARE);*/
187 handle = fopen(buf, "wt");
188 if (handle == NULL) {
190 osi_panic("Cannot create log file", __FILE__, __LINE__);
192 osi_LogPrint(afsd_logp, handle);
195 /*FlushFileBuffers(handle);*/
196 /*CloseHandle(handle);*/
200 /*------------------------------------------------------------------------------
204 * Open the file containing the description of the workstation's AFS cache
205 * and pull out its contents. The format of this file is as follows:
207 * cm_mountRoot:cacheBaseDir:cacheBlocks
213 * 0 if everything went well,
217 * Nothing interesting.
221 *---------------------------------------------------------------------------*/
223 int ParseCacheInfoFile()
225 static char rn[]="ParseCacheInfoFile"; /*This routine's name*/
226 FILE *cachefd; /*Descriptor for cache info file*/
227 int parseResult; /*Result of our fscanf()*/
229 char tCacheBaseDir[1024], *tbd, tCacheMountDir[1024], *tmd;
230 /*char cacheBaseDir[1024]; /* cache in mem, this is ignored */
233 printf("%s: Opening cache info file '%s'...\n",
234 rn, cm_CacheInfoPath);
236 cachefd = fopen(cm_CacheInfoPath, "r");
238 printf("%s: Can't read cache info file '%s'\n",
239 rn, cm_CacheInfoPath);
244 * Parse the contents of the cache info file. All chars up to the first
245 * colon are the AFS mount directory, all chars to the next colon are the
246 * full path name of the workstation cache directory and all remaining chars
247 * represent the number of blocks in the cache.
249 tCacheMountDir[0] = tCacheBaseDir[0] = '\0';
250 parseResult = fscanf(cachefd,
251 "%1024[^;];%1024[^;];%d",
252 tCacheMountDir, tCacheBaseDir, &tCacheBlocks);
255 * Regardless of how the parse went, we close the cache info file.
259 if (parseResult == EOF || parseResult < 3) {
260 printf("%s: Format error in cache info file!\n",
262 if (parseResult == EOF)
263 printf("\tEOF encountered before any field parsed.\n");
265 printf("\t%d out of 3 fields successfully parsed.\n",
268 printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n",
269 cm_mountRoot, cm_cachePath, cacheBlocks);
273 for (tmd = tCacheMountDir; *tmd == '\n' || *tmd == ' ' || *tmd == '\t'; tmd++) ;
274 for (tbd = tCacheBaseDir; *tbd == '\n' || *tbd == ' ' || *tbd == '\t'; tbd++) ;
275 /* now copy in the fields not explicitly overridden by cmd args */
278 strcpy(cm_mountRoot, tmd);
279 cm_mountRootLen = strlen(tmd);
281 if (!sawCacheBaseDir)
282 strcpy(cm_cachePath, tbd);
284 cacheBlocks = tCacheBlocks;
287 printf("%s: Cache info file successfully parsed:\n",
289 printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n",
290 tmd, tbd, tCacheBlocks);
292 /*printf("cm_cachePath: %s\n", cm_cachePath);*/
294 /*PartSizeOverflow(tbd, cacheBlocks);*/
300 * AFSD Initialization
303 int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock)
312 char rootCellName[256];
313 struct rx_service *serverp;
314 static struct rx_securityClass *nullServerSecurityClassp;
320 struct cmd_syndesc *ts;
325 WSAStartup(0x0101, &WSAjunk);*/
328 /* setup osidebug server at RPC slot 1000 */
329 osi_LongToUID(1000, &debugID);
330 code = osi_InitDebug(&debugID);
331 afsi_log("osi_InitDebug code %d", code);
332 // osi_LockTypeSetDefault("stat"); /* comment this out for speed *
334 *reasonP = "unknown error";
340 gethostname(cm_HostName, sizeof(cm_HostName));
342 /* For some reason, we may be getting space-padded hostnames.
343 If so, we take out the padding so that we can append -AFS later. */
345 char *space = strchr(cm_HostName,' ');
346 if (space) *space = '\0';
349 afsi_log("gethostname %s", cm_HostName);
350 thp = gethostbyname(cm_HostName);
351 memcpy(&cm_HostAddr, thp->h_addr_list[0], 4);
353 /* seed random number generator */
354 srand(ntohl(cm_HostAddr));
356 /* Get configuration parameters from command line */
358 /* call atoi on the appropriate parsed results */
360 if (!as->parms[20].items) {
362 fprintf(stderr, "Please do not run this program directly. Use the AFS Client Windows loader\nto start AFS.\n");
366 if (as->parms[0].items) {
368 LANadapter = atoi(as->parms[0].items->data);
370 afsi_log("LAN adapter number %d", LANadapter);
375 afsi_log("Default LAN adapter number");
378 if (as->parms[1].items) {
380 numSvThreads = atoi(as->parms[1].items->data);
381 afsi_log("%d server threads", numSvThreads);
385 numSvThreads = CM_CONFIGDEFAULT_SVTHREADS;
386 afsi_log("Defaulting to %d server threads", numSvThreads);
389 if (as->parms[2].items) {
391 strcpy(cm_rootVolumeName, as->parms[2].items->data);
393 afsi_log("Root volume %s", cm_rootVolumeName);
397 strcpy(cm_rootVolumeName, "root.afs");
398 afsi_log("Default root volume name root.afs");
401 if (as->parms[3].items) {
403 stats = atoi(as->parms[3].items->data);
404 afsi_log("Status cache size %d", stats);
408 stats = CM_CONFIGDEFAULT_STATS;
409 afsi_log("Default status cache size %d", stats);
412 if (as->parms[4].items) {
417 if (as->parms[5].items) {
419 /* no-op; cache is in memory, not mapped file */
420 strcpy(cm_cachePath, as->parms[5].items->data);
424 if (as->parms[6].items) {
426 strcpy(cm_mountRoot, as->parms[6].items->data);
427 cm_mountRootLen = strlen(cm_mountRoot);
429 afsi_log("Mount root %s", cm_mountRoot);
433 strcpy(cm_mountRoot, "/afs");
438 if (as->parms[7].items) {
440 numBkgD = atoi(as->parms[7].items->data);
441 afsi_log("%d background daemons", numBkgD);
445 numBkgD = CM_CONFIGDEFAULT_DAEMONS;
446 afsi_log("Defaulting to %d background daemons", numBkgD);
449 if (as->parms[8].items) {
451 cacheSetTime = FALSE;
454 if (as->parms[9].items) {
459 if (as->parms[10].items) {
465 if (as->parms[11].items) {
467 chunkSize = atoi(as->parms[11].items->data);
468 if (chunkSize < 12 || chunkSize > 30) {
469 afsi_log("Invalid chunk size %d, using default",
471 logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE;
474 logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE;
475 afsi_log("Default chunk size %d", logChunkSize);
477 cm_logChunkSize = logChunkSize;
478 cm_chunkSize = 1 << logChunkSize;
480 if (as->parms[12].items) {
482 cacheSize = atoi(as->parms[12].items->data);
483 afsi_log("Cache size %d", cacheSize);
488 cacheSize = CM_CONFIGDEFAULT_CACHESIZE;
489 afsi_log("Default cache size %d", cacheSize);
492 afsconf_path = getenv("AFSCONF");
494 strcpy(cm_confDir, AFSDIR_CLIENT_ETC_DIRPATH);
496 strcpy(cm_confDir, afsconf_path);
497 if (as->parms[13].items) {
499 strcpy(cm_confDir, as->parms[13].items->data);
502 sprintf(cm_CacheInfoPath, "%s/%s", cm_confDir, CACHEINFOFILE);
504 sprintf(cm_AFSLogFile, "%s/%s", cm_confDir, AFSLOGFILE);
505 if (as->parms[14].items) {
507 strcpy(cm_AFSLogFile, as->parms[14].items->data);
510 if (as->parms[15].items) {
515 if (as->parms[16].items) {
519 * Cold shutdown is the default
521 printf("afsd: Shutting down all afs processes and afs state\n");
522 /*call_syscall(AFSOP_SHUTDOWN, 1);*/
526 if (as->parms[17].items) {
528 strcpy(cm_sysName, as->parms[17].items->data);
531 strcpy(cm_sysName, "i386_win95");
533 if (as->parms[18].items) {
536 afsi_log("Set for %s service",
537 isGateway ? "gateway" : "stand-alone");
542 if (as->parms[19].items) {
544 traceBufSize = atoi(as->parms[19].items->data);
545 afsi_log("Trace Buffer size %d", traceBufSize);
549 traceBufSize = CM_CONFIGDEFAULT_TRACEBUFSIZE;
550 afsi_log("Default trace buffer size %d", traceBufSize);
553 if (as->parms[21].items) {
555 diskCacheSize = atoi(as->parms[21].items->data);
556 cm_diskCacheEnabled = 1;
557 afsi_log("Disk cache size %d K", diskCacheSize);
558 /*printf("Disk cache size %d K", diskCacheSize);*/
559 sawDiskCacheSize = 1;
563 diskCacheSize = 50000; /*CM_CONFIGDEFAULT_DISKCACHESIZE;*/
564 afsi_log("Default disk cache size %d", diskCacheSize);
567 if (as->parms[22].items) {
572 if (as->parms[23].items) {
574 cm_freelanceEnabled = 1;
577 if (ParseCacheInfoFile()) {
581 /* setup early variables */
582 /* These both used to be configurable. */
584 buf_bufferSize = CM_CONFIGDEFAULT_BLOCKSIZE;
586 /* turn from 1024 byte units into memory blocks */
587 cacheBlocks = (cacheSize * 1024) / buf_bufferSize;
588 afs_diskCacheChunks = (diskCacheSize * 1024) / buf_bufferSize;
589 /*printf("afs_diskCacheChunks=%d\n", afs_diskCacheChunks);*/
592 * Save client configuration for GetCacheConfig requests
594 cm_initParams.nChunkFiles = 0;
595 cm_initParams.nStatCaches = stats;
596 cm_initParams.nDataCaches = 0;
597 cm_initParams.nVolumeCaches = 0;
598 cm_initParams.firstChunkSize = cm_chunkSize;
599 cm_initParams.otherChunkSize = cm_chunkSize;
600 cm_initParams.cacheSize = cacheSize;
601 cm_initParams.setTime = 0;
602 cm_initParams.memCache = 0;
604 /* setup and enable debug log */
605 afsd_logp = osi_LogCreate("afsd", traceBufSize);
606 afsi_log("osi_LogCreate log addr %x", afsd_logp);
607 osi_LogEnable(afsd_logp);
611 /* get network related info */
612 cm_noIPAddr = CM_MAXINTERFACE_ADDR;
613 code = syscfg_GetIFInfo(&cm_noIPAddr,
614 cm_IPAddr, cm_SubnetMask,
615 cm_NetMtu, cm_NetFlags);
617 if ( (cm_noIPAddr <= 0) || (code <= 0 ) )
618 afsi_log("syscfg_GetIFInfo error code %d", code);
620 afsi_log("First Network address %x SubnetMask %x",
621 cm_IPAddr[0], cm_SubnetMask[0]);
624 /* initialize RX, and tell it to listen to port 7001, which is used for
625 * callback RPC messages.
627 code = rx_Init(htons(7001));
628 afsi_log("rx_Init code %x", code);
630 *reasonP = "afsd: failed to init rx client on port 7001";
634 /* Initialize the RPC server for session keys */
637 /* create an unauthenticated service #1 for callbacks */
638 nullServerSecurityClassp = rxnull_NewServerSecurityObject();
639 serverp = rx_NewService(0, 1, "AFS", &nullServerSecurityClassp, 1,
640 RXAFSCB_ExecuteRequest);
641 afsi_log("rx_NewService addr %x", serverp);
642 if (serverp == NULL) {
643 *reasonP = "unknown error";
647 nullServerSecurityClassp = rxnull_NewServerSecurityObject();
648 serverp = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats",
649 &nullServerSecurityClassp, 1, RXSTATS_ExecuteRequest);
650 afsi_log("rx_NewService addr %x", serverp);
651 if (serverp == NULL) {
652 *reasonP = "unknown error";
656 /* start server threads, *not* donating this one to the pool */
658 afsi_log("rx_StartServer");
661 /* initialize dns lookup */
662 if (cm_InitDNS(cm_dnsEnabled) == -1)
663 cm_dnsEnabled = 0; /* init failed, so deactivate */
664 afsi_log("cm_InitDNS %d", cm_dnsEnabled);
667 /* init user daemon, and other packages */
670 cm_InitACLCache(2*stats);
686 cm_InitSCache(stats);
688 code = cm_InitDCache(0, cacheBlocks);
690 afsi_log("cm_InitDCache code %x", code);
692 *reasonP = "error initializing cache";
696 code = cm_GetRootCellName(rootCellName);
697 afsi_log("cm_GetRootCellName code %d rcn %s", code,
698 (code ? "<none>" : rootCellName));
699 if (code != 0 && !cm_freelanceEnabled) {
700 *reasonP = "can't find root cell name in ThisCell";
703 else if (cm_freelanceEnabled)
706 if (code == 0 && !cm_freelanceEnabled) {
707 cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE);
708 afsi_log("cm_GetCell addr %x", cm_rootCellp);
709 if (cm_rootCellp == NULL) {
710 *reasonP = "can't find root cell in CellServDB";
715 #ifdef AFS_FREELANCE_CLIENT
716 if (cm_freelanceEnabled)
723 int afsd_InitDaemons(char **reasonP)
730 /* this should really be in an init daemon from here on down */
732 if (!cm_freelanceEnabled) {
733 code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp, &req, CM_FLAG_CREATE, &cm_rootVolumep);
734 afsi_log("cm_GetVolumeByName code %x root vol %x", code,
735 (code ? 0xffffffff : cm_rootVolumep));
737 *reasonP = "can't find root volume in root cell";
742 /* compute the root fid */
743 if (!cm_freelanceEnabled) {
744 cm_rootFid.cell = cm_rootCellp->cellID;
745 cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep);
746 cm_rootFid.vnode = 1;
747 cm_rootFid.unique = 1;
750 cm_FakeRootFid(&cm_rootFid);
752 code = cm_GetSCache(&cm_rootFid, &cm_rootSCachep, cm_rootUserp, &req);
753 afsi_log("cm_GetSCache code %x scache %x", code,
754 (code ? 0xffffffff : cm_rootSCachep));
756 *reasonP = "unknown error";
760 cm_InitDaemon(numBkgD);
761 afsi_log("cm_InitDaemon");
766 int afsd_InitSMB(char **reasonP)
771 /* Do this last so that we don't handle requests before init is done.
772 * Here we initialize the SMB listener.
774 strcpy(hostName, cm_HostName);
775 ctemp = strchr(hostName, '.'); /* turn ntdfs.* into ntdfs */
776 if (ctemp) *ctemp = 0;
777 hostName[11] = 0; /* ensure that even after adding the -A, we
778 * leave one byte free for the netbios server
781 strcat(hostName, "-AFS");
783 smb_Init(afsd_logp, hostName, smb_UseV3, LANadapter, numSvThreads);
784 afsi_log("smb_Init");