down-before-busy-20040723
[openafs.git] / src / WINNT / afsd / afsd_init95.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 #include <afs/param.h>
11 #include <afs/stds.h>
12 #include <afs/afs_args.h>
13
14 #include <string.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <time.h>
18 #include <stdarg.h>
19
20 #include <osi.h>
21 #include "afsd.h"
22 #include <rx/rx.h>
23 #include <rx/rx_null.h>
24 #include <afs/cmd.h>
25 #include <netdb.h>
26 #include "cm_rpc.h"
27
28 #define AFSDIR_CLIENT_ETC_DIRPATH "c:/"
29 #define AFSLOGFILE "afs.log"
30 #define CACHEINFOFILE "cache.info"
31
32 extern int RXAFSCB_ExecuteRequest();
33 extern int RXSTATS_ExecuteRequest();
34
35 osi_log_t *afsd_logp;
36
37 char cm_rootVolumeName[64];
38 DWORD cm_rootVolumeNameLen;
39 cm_volume_t *cm_rootVolumep = NULL;
40 cm_cell_t *cm_rootCellp = NULL;
41 cm_fid_t cm_rootFid;
42 cm_scache_t *cm_rootSCachep;
43 char cm_mountRoot[1024];
44 DWORD cm_mountRootLen;
45 int cm_logChunkSize;
46 int cm_chunkSize;
47 int afs_diskCacheChunks;
48 char cm_cachePath[128];
49 int cm_diskCacheEnabled = 0;
50 #ifdef AFS_AFSDB_ENV
51 extern int cm_dnsEnabled;
52 #endif
53
54 #ifdef AFS_FREELANCE_CLIENT
55 extern int cm_freelanceEnabled;
56 char *cm_FakeRootDir;
57 #endif /* freelance */
58
59 int smb_UseV3;
60
61 int LANadapter;
62 int lanAdaptSet = 0;
63 int rootVolSet = 0;
64 int cacheSetTime = TRUE;
65 int afsd_verbose = 0;
66 int chunkSize;
67
68 int numBkgD;
69 int numSvThreads;
70
71 int traceOnPanic = 0;
72
73 int logReady = 0;
74
75 char cm_HostName[200];
76 long cm_HostAddr;
77
78 /*char cm_CachePath[200];*/
79 /*DWORD cm_CachePathLen;*/
80 char cm_CacheInfoPath[1024];
81 int cacheBlocks;
82 int sawCacheSize=0, sawDiskCacheSize=0, sawMountRoot=0;
83 int sawCacheBaseDir=0;
84 char cm_AFSLogFile[200];
85 int afsd_CloseSynch = 0;
86 int afs_shutdown = 0;
87 char cm_confDir[200];
88
89 BOOL isGateway = FALSE;
90 BOOL reportSessionStartups = FALSE;
91
92 int afsd_debug;
93 cm_initparams_v1 cm_initParams;
94
95
96 /*
97  * AFSD Initialization Log
98  *
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.
102  */
103
104 FILE *afsi_file;
105
106 void
107 afsi_start()
108 {
109         char wd[100];
110         char t[100], u[100];
111         int zilch;
112         int code;
113         time_t now;
114         char *p;
115
116         afsi_file = NULL;
117         /*code = GetWindowsDirectory(wd, sizeof(wd));
118           if (code == 0) return;*/
119         strcpy (wd, "C:");
120         strcat(wd, "\\afsd_init.log");
121         /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/
122         time (&now);
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);
129         
130         /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, u, sizeof(u));*/
131         time (&now);
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));*/
141         fputs(t, afsi_file);
142         fputs(u, afsi_file);
143 }
144
145 void
146 afsi_log(char *pattern, ...)
147 {
148         char s[100], t[100], u[100];
149         int zilch;
150         time_t now;
151         va_list ap;
152 #ifndef DEBUG
153         return;
154 #endif
155         va_start(ap, pattern);
156
157         vsprintf(s, pattern, ap);
158         /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/
159         time(&now);
160         strcpy(t, asctime(localtime(&now)));
161         sprintf(u, "%s: %s\n", t, s);
162         if (afsi_file != NULL)
163           /* fputs(u, stderr); */
164           fputs(u, afsi_file);
165           /*write(afsi_file, u, strlen(u));*/
166         /*WriteFile(afsi_file, u, strlen(u), &zilch, NULL);*/
167 }
168
169 /*
170  * Standard AFSD trace
171  */
172
173 void afsd_ForceTrace(BOOL flush)
174 {
175         FILE *handle;
176         int len;
177         char buf[100];
178
179         if (!logReady) return;
180
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) {
189                 logReady = 0;
190                 osi_panic("Cannot create log file", __FILE__, __LINE__);
191         }
192         osi_LogPrint(afsd_logp, handle);
193         if (flush)
194           fflush(handle);
195         /*FlushFileBuffers(handle);*/
196         /*CloseHandle(handle);*/
197         fclose(handle);
198 }
199
200 /*------------------------------------------------------------------------------
201   * ParseCacheInfoFile
202   *
203   * Description:
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:
206   *
207   *         cm_mountRoot:cacheBaseDir:cacheBlocks
208   *
209   * Arguments:
210   *     None.
211   *
212   * Returns:
213   *     0 if everything went well,
214   *     1 otherwise.
215   *
216   * Environment:
217   *     Nothing interesting.
218   *
219   *  Side Effects:
220   *     Sets globals.
221   *---------------------------------------------------------------------------*/
222
223 int ParseCacheInfoFile()
224 {
225     static char rn[]="ParseCacheInfoFile";      /*This routine's name*/
226     FILE *cachefd;                              /*Descriptor for cache info file*/
227     int parseResult;                            /*Result of our fscanf()*/
228     int32 tCacheBlocks;
229     char tCacheBaseDir[1024], *tbd, tCacheMountDir[1024], *tmd;
230     /*char cacheBaseDir[1024];  /* cache in mem, this is ignored */
231
232     if (afsd_debug)
233         printf("%s: Opening cache info file '%s'...\n",
234             rn, cm_CacheInfoPath);
235
236     cachefd = fopen(cm_CacheInfoPath, "r");
237     if (!cachefd) {
238         printf("%s: Can't read cache info file '%s'\n",
239                rn, cm_CacheInfoPath);
240         return(1);
241     }
242
243     /*
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.
248      */
249     tCacheMountDir[0] = tCacheBaseDir[0] = '\0';
250     parseResult = fscanf(cachefd,
251                           "%1024[^;];%1024[^;];%d",
252                           tCacheMountDir, tCacheBaseDir, &tCacheBlocks);
253
254     /*
255      * Regardless of how the parse went, we close the cache info file.
256      */
257     fclose(cachefd);
258
259     if (parseResult == EOF || parseResult < 3) {
260         printf("%s: Format error in cache info file!\n",
261                rn);
262         if (parseResult == EOF)
263             printf("\tEOF encountered before any field parsed.\n");
264         else
265             printf("\t%d out of 3 fields successfully parsed.\n",
266                    parseResult);
267
268         printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n",
269                cm_mountRoot, cm_cachePath, cacheBlocks);
270         return(1);
271     }
272
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 */
276     if (!sawMountRoot) 
277     {
278         strcpy(cm_mountRoot, tmd);
279         cm_mountRootLen = strlen(tmd);
280     }
281     if (!sawCacheBaseDir)
282       strcpy(cm_cachePath, tbd);
283     if  (!sawCacheSize)
284         cacheBlocks = tCacheBlocks;
285
286     if (afsd_debug) {
287         printf("%s: Cache info file successfully parsed:\n",
288                rn);
289         printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n",
290                tmd, tbd, tCacheBlocks);
291     }
292     /*printf("cm_cachePath: %s\n", cm_cachePath);*/
293
294     /*PartSizeOverflow(tbd, cacheBlocks);*/
295
296     return(0);
297 }
298
299 /*
300  * AFSD Initialization
301  */
302
303 int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock)
304 {
305         osi_uid_t debugID;
306         long cacheBlocks;
307         long cacheSize;
308         long logChunkSize;
309         long stats;
310         long traceBufSize;
311         long ltt, ltto;
312         char rootCellName[256];
313         struct rx_service *serverp;
314         static struct rx_securityClass *nullServerSecurityClassp;
315         struct hostent *thp;
316         char *msgBuf;
317         char buf[200];
318         DWORD dummyLen;
319         long code;
320         struct cmd_syndesc *ts;
321         char *afsconf_path;
322         long diskCacheSize;
323         /*WSADATA WSAjunk;
324
325           WSAStartup(0x0101, &WSAjunk);*/
326
327 #ifndef DJGPP
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 *
333         if (code != 0) {
334                 *reasonP = "unknown error";
335                 return -1;
336         }
337 #endif 
338
339         /* who are we ? */
340         gethostname(cm_HostName, sizeof(cm_HostName));
341 #ifdef DJGPP
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. */
344         {
345           char *space = strchr(cm_HostName,' ');
346           if (space) *space = '\0';
347         }
348 #endif
349         afsi_log("gethostname %s", cm_HostName);
350         thp = gethostbyname(cm_HostName);
351         memcpy(&cm_HostAddr, thp->h_addr_list[0], 4);
352
353         /* seed random number generator */
354         srand(ntohl(cm_HostAddr));
355
356         /* Get configuration parameters from command line */
357
358         /* call atoi on the appropriate parsed results */
359
360         if (!as->parms[20].items) {
361           /* -startup */
362           fprintf(stderr, "Please do not run this program directly.  Use the AFS Client Windows loader\nto start AFS.\n");
363           exit(1);
364         }
365
366         if (as->parms[0].items) {
367           /* -lanadapt */
368           LANadapter = atoi(as->parms[0].items->data);
369           lanAdaptSet = 1;
370           afsi_log("LAN adapter number %d", LANadapter);
371         }
372         else
373         {
374           LANadapter = -1;
375           afsi_log("Default LAN adapter number");
376         }
377         
378         if (as->parms[1].items) {
379           /* -threads */
380           numSvThreads = atoi(as->parms[1].items->data);
381           afsi_log("%d server threads", numSvThreads);
382         }
383         else
384         {
385           numSvThreads = CM_CONFIGDEFAULT_SVTHREADS;
386           afsi_log("Defaulting to %d server threads", numSvThreads);
387         }
388         
389         if (as->parms[2].items) {
390           /* -rootvol */
391           strcpy(cm_rootVolumeName, as->parms[2].items->data);
392           rootVolSet = 1;
393           afsi_log("Root volume %s", cm_rootVolumeName);
394         }
395         else
396         {
397           strcpy(cm_rootVolumeName, "root.afs");
398           afsi_log("Default root volume name root.afs");
399         }
400         
401         if (as->parms[3].items) {
402           /* -stat */
403           stats = atoi(as->parms[3].items->data);
404           afsi_log("Status cache size %d", stats);
405         }
406         else
407         {
408           stats = CM_CONFIGDEFAULT_STATS;
409           afsi_log("Default status cache size %d", stats);
410         }
411         
412         if (as->parms[4].items) {
413           /* -memcache */
414           /* no-op */
415         }
416         
417         if (as->parms[5].items) {
418           /* -cachedir */
419           /* no-op; cache is in memory, not mapped file */
420           strcpy(cm_cachePath, as->parms[5].items->data);
421           sawCacheBaseDir = 1;
422         }
423         
424         if (as->parms[6].items) {
425           /* -mountdir */
426           strcpy(cm_mountRoot, as->parms[6].items->data);
427           cm_mountRootLen = strlen(cm_mountRoot);
428           sawMountRoot = 1;
429           afsi_log("Mount root %s", cm_mountRoot);
430         }
431         else
432         {
433           strcpy(cm_mountRoot, "/afs");
434           cm_mountRootLen = 4;
435           /* Don't log */
436         }
437         
438         if (as->parms[7].items) {
439           /* -daemons */
440           numBkgD = atoi(as->parms[7].items->data);
441           afsi_log("%d background daemons", numBkgD);
442         }
443         else
444         {
445           numBkgD = CM_CONFIGDEFAULT_DAEMONS;
446           afsi_log("Defaulting to %d background daemons", numBkgD);
447         }
448         
449         if (as->parms[8].items) {
450           /* -nosettime */
451           cacheSetTime = FALSE;
452         }
453         
454         if (as->parms[9].items) {
455           /* -verbose */
456           afsd_verbose = 1;
457         }
458         
459         if (as->parms[10].items) {
460           /* -debug */
461           afsd_debug = 1;
462           afsd_verbose = 1;
463         }
464         
465         if (as->parms[11].items) {
466           /* -chunksize */
467           chunkSize = atoi(as->parms[11].items->data);
468           if (chunkSize < 12 || chunkSize > 30) {
469             afsi_log("Invalid chunk size %d, using default",
470                      logChunkSize);
471             logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE;
472           }
473         } else {
474           logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE;
475           afsi_log("Default chunk size %d", logChunkSize);
476         }
477         cm_logChunkSize = logChunkSize;
478         cm_chunkSize = 1 << logChunkSize;
479         
480         if (as->parms[12].items) {
481           /* -dcache */
482           cacheSize = atoi(as->parms[12].items->data);
483           afsi_log("Cache size %d", cacheSize);
484           sawCacheSize = 1;
485         }
486         else
487         {
488           cacheSize = CM_CONFIGDEFAULT_CACHESIZE;
489           afsi_log("Default cache size %d", cacheSize);
490         }
491         
492         afsconf_path = getenv("AFSCONF");
493         if (!afsconf_path)
494           strcpy(cm_confDir, AFSDIR_CLIENT_ETC_DIRPATH);
495         else
496           strcpy(cm_confDir, afsconf_path);
497         if (as->parms[13].items) {
498           /* -confdir */
499           strcpy(cm_confDir, as->parms[13].items->data);
500         }
501
502         sprintf(cm_CacheInfoPath,  "%s/%s", cm_confDir, CACHEINFOFILE);
503
504         sprintf(cm_AFSLogFile,  "%s/%s", cm_confDir, AFSLOGFILE);
505         if (as->parms[14].items) {
506           /* -logfile */
507           strcpy(cm_AFSLogFile, as->parms[14].items->data);
508         }
509
510         if (as->parms[15].items) {
511           /* -waitclose */
512           afsd_CloseSynch = 1;
513         }
514
515         if (as->parms[16].items) {
516           /* -shutdown */
517           afs_shutdown = 1;
518           /* 
519            * Cold shutdown is the default
520            */
521           printf("afsd: Shutting down all afs processes and afs state\n");
522           /*call_syscall(AFSOP_SHUTDOWN, 1);*/
523           exit(0);
524         }
525
526         if (as->parms[17].items) {
527           /* -sysname */
528           strcpy(cm_sysName, as->parms[17].items->data);
529         }
530         else
531           strcpy(cm_sysName, "i386_win95");
532         
533         if (as->parms[18].items) {
534           /* -gateway */
535           isGateway = 1;
536           afsi_log("Set for %s service",
537                    isGateway ? "gateway" : "stand-alone");
538         }
539         else
540           isGateway = 0;
541
542         if (as->parms[19].items) {
543           /* -tracebuf */
544           traceBufSize = atoi(as->parms[19].items->data);
545           afsi_log("Trace Buffer size %d", traceBufSize);
546         }
547         else
548         {
549           traceBufSize = CM_CONFIGDEFAULT_TRACEBUFSIZE;
550           afsi_log("Default trace buffer size %d", traceBufSize);
551         }
552         
553         if (as->parms[21].items) {
554           /* -diskcache */
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;
560         }
561         else
562         {
563           diskCacheSize = 50000; /*CM_CONFIGDEFAULT_DISKCACHESIZE;*/
564           afsi_log("Default disk cache size %d", diskCacheSize);
565         }
566
567         if (as->parms[22].items) {
568            /* -noafsdb */
569            cm_dnsEnabled = 0;
570         }
571
572         if (as->parms[23].items) {
573            /* -freelance */
574            cm_freelanceEnabled = 1;
575         }
576
577         if (ParseCacheInfoFile()) {
578           exit(1);
579         }
580
581         /* setup early variables */
582         /* These both used to be configurable. */
583         smb_UseV3 = 1;
584         buf_bufferSize = CM_CONFIGDEFAULT_BLOCKSIZE;
585
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);*/
590
591         /*
592          * Save client configuration for GetCacheConfig requests
593          */
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;
603         
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);
608         logReady = 1;
609
610 #if 0
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);
616
617         if ( (cm_noIPAddr <= 0) || (code <= 0 ) )
618             afsi_log("syscfg_GetIFInfo error code %d", code);
619         else
620             afsi_log("First Network address %x SubnetMask %x",
621                      cm_IPAddr[0], cm_SubnetMask[0]);
622 #endif
623
624         /* initialize RX, and tell it to listen to port 7001, which is used for
625          * callback RPC messages.
626          */
627         code = rx_Init(htons(7001));
628         afsi_log("rx_Init code %x", code);
629         if (code != 0) {
630                 *reasonP = "afsd: failed to init rx client on port 7001";
631                 return -1;
632         }
633
634         /* Initialize the RPC server for session keys */
635         /*RpcInit();*/
636
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";
644                 return -1;
645         }
646
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";
653                 return -1;
654         }
655         
656         /* start server threads, *not* donating this one to the pool */
657         rx_StartServer(0);
658         afsi_log("rx_StartServer");
659
660 #ifdef AFS_AFSDB_ENV
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);
665 #endif
666
667         /* init user daemon, and other packages */
668         cm_InitUser();
669
670         cm_InitACLCache(2*stats);
671
672         cm_InitConn();
673
674         cm_InitCell();
675         
676         cm_InitServer();
677         
678         cm_InitVolume();
679         
680         cm_InitIoctl();
681         
682         smb_InitIoctl();
683         
684         cm_InitCallback();
685         
686         cm_InitSCache(stats);
687         
688         code = cm_InitDCache(0, cacheBlocks);
689
690         afsi_log("cm_InitDCache code %x", code);
691         if (code != 0) {
692                 *reasonP = "error initializing cache";
693                 return -1;
694         }
695
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";
701                 return -1;
702         }
703         else if (cm_freelanceEnabled)
704           cm_rootCellp = NULL;
705         
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";
711             return -1;
712           }
713         }
714
715 #ifdef AFS_FREELANCE_CLIENT
716         if (cm_freelanceEnabled)
717           cm_InitFreelance();
718 #endif
719
720         return 0;
721 }
722
723 int afsd_InitDaemons(char **reasonP)
724 {
725         long code;
726         cm_req_t req;
727
728         cm_InitReq(&req);
729
730         /* this should really be in an init daemon from here on down */
731
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));
736           if (code != 0) {
737             *reasonP = "can't find root volume in root cell";
738             return -1;
739           }
740         }
741
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;
748         }
749         else
750           cm_FakeRootFid(&cm_rootFid);
751         
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));
755         if (code != 0) {
756                 *reasonP = "unknown error";
757                 return -1;
758         }
759
760         cm_InitDaemon(numBkgD);
761         afsi_log("cm_InitDaemon");
762
763         return 0;
764 }
765
766 int afsd_InitSMB(char **reasonP)
767 {
768         char hostName[200];
769         char *ctemp;
770
771         /* Do this last so that we don't handle requests before init is done.
772          * Here we initialize the SMB listener.
773          */
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
779                                  * type.
780                                  */
781         strcat(hostName, "-AFS");
782         strupr(hostName);
783         smb_Init(afsd_logp, hostName, smb_UseV3, LANadapter, numSvThreads);
784         afsi_log("smb_Init");
785
786         return 0;
787 }
788