winnt-win2000-win98-afs-client-updates-20010623
[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
51 int smb_UseV3;
52
53 int LANadapter;
54 int lanAdaptSet = 0;
55 int rootVolSet = 0;
56 int cacheSetTime = TRUE;
57 int afsd_verbose = 0;
58 int chunkSize;
59
60 int numBkgD;
61 int numSvThreads;
62
63 int traceOnPanic = 0;
64
65 int logReady = 0;
66
67 char cm_HostName[200];
68 long cm_HostAddr;
69
70 /*char cm_CachePath[200];*/
71 /*DWORD cm_CachePathLen;*/
72 char cm_CacheInfoPath[1024];
73 int cacheBlocks;
74 int sawCacheSize=0, sawDiskCacheSize=0, sawMountRoot=0;
75 int sawCacheBaseDir=0;
76 char cm_AFSLogFile[200];
77 int afsd_CloseSynch = 0;
78 int afs_shutdown = 0;
79 char cm_confDir[200];
80
81 BOOL isGateway = FALSE;
82 BOOL reportSessionStartups = FALSE;
83
84 int afsd_debug;
85 cm_initparams_v1 cm_initParams;
86
87 /*
88  * AFSD Initialization Log
89  *
90  * This is distinct from the regular debug logging facility.
91  * Log items go directly to a file, not to an array in memory, so that even
92  * if AFSD crashes, the log can be inspected.
93  */
94
95 FILE *afsi_file;
96
97 void
98 afsi_start()
99 {
100         char wd[100];
101         char t[100], u[100];
102         int zilch;
103         int code;
104         time_t now;
105         char *p;
106
107         afsi_file = NULL;
108         /*code = GetWindowsDirectory(wd, sizeof(wd));
109           if (code == 0) return;*/
110         strcpy (wd, "C:");
111         strcat(wd, "\\afsd_init.log");
112         /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/
113         time (&now);
114         strcpy(t, asctime(localtime(&now)));
115         /*afsi_file = CreateFile(wd, GENERIC_WRITE, FILE_SHARE_READ, NULL,
116           CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);*/
117         /*afsi_file = open(wd, O_RDWR | O_CREAT | O_RSHARE);*/
118         afsi_file = fopen(wd, "wt");
119         setbuf(afsi_file, NULL);
120         
121         /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, u, sizeof(u));*/
122         time (&now);
123         strcpy(u, asctime(localtime(&now)));
124         p = strchr(u, '\n'); if (p) *p = 0;
125         p = strchr(u, '\r'); if (p) *p = 0;
126         strcat(t, ": Create log file\n");
127         strcat(u, ": Created log file\n");
128         /*WriteFile(afsi_file, t, strlen(t), &zilch, NULL);
129           WriteFile(afsi_file, u, strlen(u), &zilch, NULL);*/
130         /*write(afsi_file, t, strlen(t));
131           write(afsi_file, u, strlen(u));*/
132         fputs(t, afsi_file);
133         fputs(u, afsi_file);
134 }
135
136 void
137 afsi_log(char *pattern, ...)
138 {
139         char s[100], t[100], u[100];
140         int zilch;
141         time_t now;
142         va_list ap;
143 #ifndef DEBUG
144         return;
145 #endif
146         va_start(ap, pattern);
147
148         vsprintf(s, pattern, ap);
149         /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/
150         time(&now);
151         strcpy(t, asctime(localtime(&now)));
152         sprintf(u, "%s: %s\n", t, s);
153         if (afsi_file != NULL)
154           /* fputs(u, stderr); */
155           fputs(u, afsi_file);
156           /*write(afsi_file, u, strlen(u));*/
157         /*WriteFile(afsi_file, u, strlen(u), &zilch, NULL);*/
158 }
159
160 /*
161  * Standard AFSD trace
162  */
163
164 void afsd_ForceTrace(BOOL flush)
165 {
166         FILE *handle;
167         int len;
168         char buf[100];
169
170         if (!logReady) return;
171
172         /*len = GetTempPath(99, buf);*/
173         /*strcpy(&buf[len], "/afsd.log");*/
174         strcpy(buf, "c:/afsd.log");
175         /*handle = CreateFile(buf, GENERIC_WRITE, FILE_SHARE_READ,
176           NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);*/
177         /*handle = open(buf, O_RDWR | O_CREAT | O_RSHARE);*/
178         handle = fopen(buf, "wt");
179         if (handle == NULL) {
180                 logReady = 0;
181                 osi_panic("Cannot create log file", __FILE__, __LINE__);
182         }
183         osi_LogPrint(afsd_logp, handle);
184         if (flush)
185           fflush(handle);
186         /*FlushFileBuffers(handle);*/
187         /*CloseHandle(handle);*/
188         fclose(handle);
189 }
190
191 /*------------------------------------------------------------------------------
192   * ParseCacheInfoFile
193   *
194   * Description:
195   *     Open the file containing the description of the workstation's AFS cache
196   *     and pull out its contents.  The format of this file is as follows:
197   *
198   *         cm_mountRoot:cacheBaseDir:cacheBlocks
199   *
200   * Arguments:
201   *     None.
202   *
203   * Returns:
204   *     0 if everything went well,
205   *     1 otherwise.
206   *
207   * Environment:
208   *     Nothing interesting.
209   *
210   *  Side Effects:
211   *     Sets globals.
212   *---------------------------------------------------------------------------*/
213
214 int ParseCacheInfoFile()
215 {
216     static char rn[]="ParseCacheInfoFile";      /*This routine's name*/
217     FILE *cachefd;                              /*Descriptor for cache info file*/
218     int parseResult;                            /*Result of our fscanf()*/
219     int32 tCacheBlocks;
220     char tCacheBaseDir[1024], *tbd, tCacheMountDir[1024], *tmd;
221     /*char cacheBaseDir[1024];  /* cache in mem, this is ignored */
222
223     if (afsd_debug)
224         printf("%s: Opening cache info file '%s'...\n",
225             rn, cm_CacheInfoPath);
226
227     cachefd = fopen(cm_CacheInfoPath, "r");
228     if (!cachefd) {
229         printf("%s: Can't read cache info file '%s'\n",
230                rn, cm_CacheInfoPath);
231         return(1);
232     }
233
234     /*
235      * Parse the contents of the cache info file.  All chars up to the first
236      * colon are the AFS mount directory, all chars to the next colon are the
237      * full path name of the workstation cache directory and all remaining chars
238      * represent the number of blocks in the cache.
239      */
240     tCacheMountDir[0] = tCacheBaseDir[0] = '\0';
241     parseResult = fscanf(cachefd,
242                           "%1024[^;];%1024[^;];%d",
243                           tCacheMountDir, tCacheBaseDir, &tCacheBlocks);
244
245     /*
246      * Regardless of how the parse went, we close the cache info file.
247      */
248     fclose(cachefd);
249
250     if (parseResult == EOF || parseResult < 3) {
251         printf("%s: Format error in cache info file!\n",
252                rn);
253         if (parseResult == EOF)
254             printf("\tEOF encountered before any field parsed.\n");
255         else
256             printf("\t%d out of 3 fields successfully parsed.\n",
257                    parseResult);
258
259         printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n",
260                cm_mountRoot, cm_cachePath, cacheBlocks);
261         return(1);
262     }
263
264     for (tmd = tCacheMountDir; *tmd == '\n' || *tmd == ' ' || *tmd == '\t'; tmd++) ;
265     for (tbd = tCacheBaseDir; *tbd == '\n' || *tbd == ' ' || *tbd == '\t'; tbd++) ;
266     /* now copy in the fields not explicitly overridden by cmd args */
267     if (!sawMountRoot) 
268     {
269         strcpy(cm_mountRoot, tmd);
270         cm_mountRootLen = strlen(tmd);
271     }
272     if (!sawCacheBaseDir)
273       strcpy(cm_cachePath, tbd);
274     if  (!sawCacheSize)
275         cacheBlocks = tCacheBlocks;
276
277     if (afsd_debug) {
278         printf("%s: Cache info file successfully parsed:\n",
279                rn);
280         printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n",
281                tmd, tbd, tCacheBlocks);
282     }
283     /*printf("cm_cachePath: %s\n", cm_cachePath);*/
284
285     /*PartSizeOverflow(tbd, cacheBlocks);*/
286
287     return(0);
288 }
289
290 /*
291  * AFSD Initialization
292  */
293
294 int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock)
295 {
296         osi_uid_t debugID;
297         long cacheBlocks;
298         long cacheSize;
299         long logChunkSize;
300         long stats;
301         long traceBufSize;
302         long ltt, ltto;
303         char rootCellName[256];
304         struct rx_service *serverp;
305         static struct rx_securityClass *nullServerSecurityClassp;
306         struct hostent *thp;
307         char *msgBuf;
308         char buf[200];
309         DWORD dummyLen;
310         long code;
311         struct cmd_syndesc *ts;
312         char *afsconf_path;
313         long diskCacheSize;
314         /*WSADATA WSAjunk;
315
316           WSAStartup(0x0101, &WSAjunk);*/
317
318 #ifndef DJGPP
319         /* setup osidebug server at RPC slot 1000 */
320         osi_LongToUID(1000, &debugID);
321         code = osi_InitDebug(&debugID);
322         afsi_log("osi_InitDebug code %d", code);
323 //      osi_LockTypeSetDefault("stat"); /* comment this out for speed *
324         if (code != 0) {
325                 *reasonP = "unknown error";
326                 return -1;
327         }
328 #endif 
329
330         /* who are we ? */
331         gethostname(cm_HostName, sizeof(cm_HostName));
332 #ifdef DJGPP
333         /* For some reason, we may be getting space-padded hostnames.
334            If so, we take out the padding so that we can append -AFS later. */
335         {
336           char *space = strchr(cm_HostName,' ');
337           if (space) *space = '\0';
338         }
339 #endif
340         afsi_log("gethostname %s", cm_HostName);
341         thp = gethostbyname(cm_HostName);
342         memcpy(&cm_HostAddr, thp->h_addr_list[0], 4);
343
344         /* seed random number generator */
345         srand(ntohl(cm_HostAddr));
346
347         /* Get configuration parameters from command line */
348
349         /* call atoi on the appropriate parsed results */
350
351         if (!as->parms[20].items) {
352           /* -startup */
353           fprintf(stderr, "Please do not run this program directly.  Use the AFS Client Windows loader\nto start AFS.\n");
354           exit(1);
355         }
356
357         if (as->parms[0].items) {
358           /* -lanadapt */
359           LANadapter = atoi(as->parms[0].items->data);
360           lanAdaptSet = 1;
361           afsi_log("LAN adapter number %d", LANadapter);
362         }
363         else
364         {
365           LANadapter = -1;
366           afsi_log("Default LAN adapter number");
367         }
368         
369         if (as->parms[1].items) {
370           /* -threads */
371           numSvThreads = atoi(as->parms[1].items->data);
372           afsi_log("%d server threads", numSvThreads);
373         }
374         else
375         {
376           numSvThreads = CM_CONFIGDEFAULT_SVTHREADS;
377           afsi_log("Defaulting to %d server threads", numSvThreads);
378         }
379         
380         if (as->parms[2].items) {
381           /* -rootvol */
382           strcpy(cm_rootVolumeName, as->parms[2].items->data);
383           rootVolSet = 1;
384           afsi_log("Root volume %s", cm_rootVolumeName);
385         }
386         else
387         {
388           strcpy(cm_rootVolumeName, "root.afs");
389           afsi_log("Default root volume name root.afs");
390         }
391         
392         if (as->parms[3].items) {
393           /* -stat */
394           stats = atoi(as->parms[3].items->data);
395           afsi_log("Status cache size %d", stats);
396         }
397         else
398         {
399           stats = CM_CONFIGDEFAULT_STATS;
400           afsi_log("Default status cache size %d", stats);
401         }
402         
403         if (as->parms[4].items) {
404           /* -memcache */
405           /* no-op */
406         }
407         
408         if (as->parms[5].items) {
409           /* -cachedir */
410           /* no-op; cache is in memory, not mapped file */
411           strcpy(cm_cachePath, as->parms[5].items->data);
412           sawCacheBaseDir = 1;
413         }
414         
415         if (as->parms[6].items) {
416           /* -mountdir */
417           strcpy(cm_mountRoot, as->parms[6].items->data);
418           cm_mountRootLen = strlen(cm_mountRoot);
419           sawMountRoot = 1;
420           afsi_log("Mount root %s", cm_mountRoot);
421         }
422         else
423         {
424           strcpy(cm_mountRoot, "/afs");
425           cm_mountRootLen = 4;
426           /* Don't log */
427         }
428         
429         if (as->parms[7].items) {
430           /* -daemons */
431           numBkgD = atoi(as->parms[7].items->data);
432           afsi_log("%d background daemons", numBkgD);
433         }
434         else
435         {
436           numBkgD = CM_CONFIGDEFAULT_DAEMONS;
437           afsi_log("Defaulting to %d background daemons", numBkgD);
438         }
439         
440         if (as->parms[8].items) {
441           /* -nosettime */
442           cacheSetTime = FALSE;
443         }
444         
445         if (as->parms[9].items) {
446           /* -verbose */
447           afsd_verbose = 1;
448         }
449         
450         if (as->parms[10].items) {
451           /* -debug */
452           afsd_debug = 1;
453           afsd_verbose = 1;
454         }
455         
456         if (as->parms[11].items) {
457           /* -chunksize */
458           chunkSize = atoi(as->parms[11].items->data);
459           if (chunkSize < 12 || chunkSize > 30) {
460             afsi_log("Invalid chunk size %d, using default",
461                      logChunkSize);
462             logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE;
463           }
464         } else {
465           logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE;
466           afsi_log("Default chunk size %d", logChunkSize);
467         }
468         cm_logChunkSize = logChunkSize;
469         cm_chunkSize = 1 << logChunkSize;
470         
471         if (as->parms[12].items) {
472           /* -dcache */
473           cacheSize = atoi(as->parms[12].items->data);
474           afsi_log("Cache size %d", cacheSize);
475           sawCacheSize = 1;
476         }
477         else
478         {
479           cacheSize = CM_CONFIGDEFAULT_CACHESIZE;
480           afsi_log("Default cache size %d", cacheSize);
481         }
482         
483         afsconf_path = getenv("AFSCONF");
484         if (!afsconf_path)
485           strcpy(cm_confDir, AFSDIR_CLIENT_ETC_DIRPATH);
486         else
487           strcpy(cm_confDir, afsconf_path);
488         if (as->parms[13].items) {
489           /* -confdir */
490           strcpy(cm_confDir, as->parms[13].items->data);
491         }
492
493         sprintf(cm_CacheInfoPath,  "%s/%s", cm_confDir, CACHEINFOFILE);
494
495         sprintf(cm_AFSLogFile,  "%s/%s", cm_confDir, AFSLOGFILE);
496         if (as->parms[14].items) {
497           /* -logfile */
498           strcpy(cm_AFSLogFile, as->parms[14].items->data);
499         }
500
501         if (as->parms[15].items) {
502           /* -waitclose */
503           afsd_CloseSynch = 1;
504         }
505
506         if (as->parms[16].items) {
507           /* -shutdown */
508           afs_shutdown = 1;
509           /* 
510            * Cold shutdown is the default
511            */
512           printf("afsd: Shutting down all afs processes and afs state\n");
513           /*call_syscall(AFSOP_SHUTDOWN, 1);*/
514           exit(0);
515         }
516
517         if (as->parms[17].items) {
518           /* -sysname */
519           strcpy(cm_sysName, as->parms[17].items->data);
520         }
521         else
522           strcpy(cm_sysName, "i386_win95");
523         
524         if (as->parms[18].items) {
525           /* -gateway */
526           isGateway = 1;
527           afsi_log("Set for %s service",
528                    isGateway ? "gateway" : "stand-alone");
529         }
530         else
531           isGateway = 0;
532
533         if (as->parms[19].items) {
534           /* -tracebuf */
535           traceBufSize = atoi(as->parms[19].items->data);
536           afsi_log("Trace Buffer size %d", traceBufSize);
537         }
538         else
539         {
540           traceBufSize = CM_CONFIGDEFAULT_TRACEBUFSIZE;
541           afsi_log("Default trace buffer size %d", traceBufSize);
542         }
543         
544         if (as->parms[21].items) {
545           /* -diskcache */
546           diskCacheSize = atoi(as->parms[21].items->data);
547           cm_diskCacheEnabled = 1;
548           afsi_log("Disk cache size %d K", diskCacheSize);
549           /*printf("Disk cache size %d K", diskCacheSize);*/
550           sawDiskCacheSize = 1;
551         }
552         else
553         {
554           diskCacheSize = 50000; /*CM_CONFIGDEFAULT_DISKCACHESIZE;*/
555           afsi_log("Default disk cache size %d", diskCacheSize);
556         }
557
558         if (ParseCacheInfoFile()) {
559           exit(1);
560         }
561
562         /* setup early variables */
563         /* These both used to be configurable. */
564         smb_UseV3 = 1;
565         buf_bufferSize = CM_CONFIGDEFAULT_BLOCKSIZE;
566
567         /* turn from 1024 byte units into memory blocks */
568         cacheBlocks = (cacheSize * 1024) / buf_bufferSize;
569         afs_diskCacheChunks = (diskCacheSize * 1024) / buf_bufferSize;
570         /*printf("afs_diskCacheChunks=%d\n", afs_diskCacheChunks);*/
571
572         /*
573          * Save client configuration for GetCacheConfig requests
574          */
575         cm_initParams.nChunkFiles = 0;
576         cm_initParams.nStatCaches = stats;
577         cm_initParams.nDataCaches = 0;
578         cm_initParams.nVolumeCaches = 0;
579         cm_initParams.firstChunkSize = cm_chunkSize;
580         cm_initParams.otherChunkSize = cm_chunkSize;
581         cm_initParams.cacheSize = cacheSize;
582         cm_initParams.setTime = 0;
583         cm_initParams.memCache = 0;
584         
585         /* setup and enable debug log */
586         afsd_logp = osi_LogCreate("afsd", traceBufSize);
587         afsi_log("osi_LogCreate log addr %x", afsd_logp);
588         osi_LogEnable(afsd_logp);
589         logReady = 1;
590
591 #if 0
592         /* get network related info */
593         cm_noIPAddr = CM_MAXINTERFACE_ADDR;
594         code = syscfg_GetIFInfo(&cm_noIPAddr,
595                                 cm_IPAddr, cm_SubnetMask,
596                                 cm_NetMtu, cm_NetFlags);
597
598         if ( (cm_noIPAddr <= 0) || (code <= 0 ) )
599             afsi_log("syscfg_GetIFInfo error code %d", code);
600         else
601             afsi_log("First Network address %x SubnetMask %x",
602                      cm_IPAddr[0], cm_SubnetMask[0]);
603 #endif
604
605         /* initialize RX, and tell it to listen to port 7001, which is used for
606          * callback RPC messages.
607          */
608         code = rx_Init(htons(7001));
609         afsi_log("rx_Init code %x", code);
610         if (code != 0) {
611                 *reasonP = "afsd: failed to init rx client on port 7001";
612                 return -1;
613         }
614
615         /* Initialize the RPC server for session keys */
616         /*RpcInit();*/
617
618         /* create an unauthenticated service #1 for callbacks */
619         nullServerSecurityClassp = rxnull_NewServerSecurityObject();
620         serverp = rx_NewService(0, 1, "AFS", &nullServerSecurityClassp, 1,
621                 RXAFSCB_ExecuteRequest);
622         afsi_log("rx_NewService addr %x", serverp);
623         if (serverp == NULL) {
624                 *reasonP = "unknown error";
625                 return -1;
626         }
627
628         nullServerSecurityClassp = rxnull_NewServerSecurityObject();
629         serverp = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats",
630                 &nullServerSecurityClassp, 1, RXSTATS_ExecuteRequest);
631         afsi_log("rx_NewService addr %x", serverp);
632         if (serverp == NULL) {
633                 *reasonP = "unknown error";
634                 return -1;
635         }
636         
637         /* start server threads, *not* donating this one to the pool */
638         rx_StartServer(0);
639         afsi_log("rx_StartServer");
640
641         /* init user daemon, and other packages */
642         cm_InitUser();
643
644         cm_InitACLCache(2*stats);
645
646         cm_InitConn();
647
648         cm_InitCell();
649         
650         cm_InitServer();
651         
652         cm_InitVolume();
653         
654         cm_InitIoctl();
655         
656         smb_InitIoctl();
657         
658         cm_InitCallback();
659         
660         cm_InitSCache(stats);
661         
662         code = cm_InitDCache(0, cacheBlocks);
663
664         afsi_log("cm_InitDCache code %x", code);
665         if (code != 0) {
666                 *reasonP = "error initializing cache";
667                 return -1;
668         }
669
670         code = cm_GetRootCellName(rootCellName);
671         afsi_log("cm_GetRootCellName code %d rcn %s", code,
672                  (code ? "<none>" : rootCellName));
673         if (code != 0) {
674                 *reasonP = "can't find root cell name in ThisCell";
675                 return -1;
676         }
677
678         cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE);
679         afsi_log("cm_GetCell addr %x", cm_rootCellp);
680         if (cm_rootCellp == NULL) {
681                 *reasonP = "can't find root cell in CellServDB";
682                 return -1;
683         }
684
685         return 0;
686 }
687
688 int afsd_InitDaemons(char **reasonP)
689 {
690         long code;
691         cm_req_t req;
692
693         cm_InitReq(&req);
694
695         /* this should really be in an init daemon from here on down */
696
697         code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp,                &req, CM_FLAG_CREATE, &cm_rootVolumep);
698         afsi_log("cm_GetVolumeByName code %x root vol %x", code,
699                  (code ? 0xffffffff : cm_rootVolumep));
700         if (code != 0) {
701                 *reasonP = "can't find root volume in root cell";
702                 return -1;
703         }
704
705         /* compute the root fid */
706         cm_rootFid.cell = cm_rootCellp->cellID;
707         cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep);
708         cm_rootFid.vnode = 1;
709         cm_rootFid.unique = 1;
710         
711         code = cm_GetSCache(&cm_rootFid, &cm_rootSCachep, cm_rootUserp, &req);
712         afsi_log("cm_GetSCache code %x scache %x", code,
713                  (code ? 0xffffffff : cm_rootSCachep));
714         if (code != 0) {
715                 *reasonP = "unknown error";
716                 return -1;
717         }
718
719         cm_InitDaemon(numBkgD);
720         afsi_log("cm_InitDaemon");
721
722         return 0;
723 }
724
725 int afsd_InitSMB(char **reasonP)
726 {
727         char hostName[200];
728         char *ctemp;
729
730         /* Do this last so that we don't handle requests before init is done.
731          * Here we initialize the SMB listener.
732          */
733         strcpy(hostName, cm_HostName);
734         ctemp = strchr(hostName, '.');  /* turn ntdfs.* into ntdfs */
735         if (ctemp) *ctemp = 0;
736         hostName[11] = 0;       /* ensure that even after adding the -A, we
737                                  * leave one byte free for the netbios server
738                                  * type.
739                                  */
740         strcat(hostName, "-AFS");
741         strupr(hostName);
742         smb_Init(afsd_logp, hostName, smb_UseV3, LANadapter, numSvThreads);
743         afsi_log("smb_Init");
744
745         return 0;
746 }