1 This document is current as of release 1.6.0b. It has not been updated
2 to reflect the changes due to the use of the AFSRedir.sys file system
3 redirector driver in 1.7.0100 and later.
5 How to determine if OpenAFS is installed?
7 When the OpenAFS Client Service is installed there will be several
10 HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon
11 "ImagePath" = "path to afsd_service.exe"
13 HKLM\SOFTWARE\TransarcCorporation\AFS Client\CurrentVersion
14 "PathName" = "the path to the client installation directory"
19 BOOL IsAFSServerInstalled (void)
21 BOOL fInstalled = FALSE;
22 TCHAR szKey[] = TEXT("HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon");
23 LPCTSTR pch = lstrchr (szKey, TEXT('\\'));
26 if (RegOpenKey (HKEY_LOCAL_MACHINE, &pch[1], &hk) == 0)
35 How to determine if OpenAFS is active?
37 The AFS Client Service is normally started automatically at system boot.
38 The state of the service may be queried by asking the Windows Service
41 BOOL IsAFSServiceRunning (void)
43 SERVICE_STATUS Status;
44 memset (&Status, 0x00, sizeof(Status));
45 Status.dwCurrentState = SERVICE_STOPPED;
48 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
51 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
53 QueryServiceStatus (hService, &Status);
54 CloseServiceHandle (hService);
56 CloseServiceHandle (hManager);
58 return (Status.dwCurrentState == SERVICE_RUNNING);
61 How to determine the AFS UNC Service Name?
63 The local UNC service name registered by the OpenAFS Client Service SMB/CIFS
64 Server depends on whether or not a Microsoft Loopback Adapter has been
65 installed and the contents of a registry value. The loopback adapter is
66 important because if the service cannot bind itself to a loopback adapter
67 then the registered SMB/CIFS service name must be unique to the WINS name
68 space. When the loopback adapter is installed, a globally common name such
71 If the loopback adapter is installed the UNC server name will be the value at:
73 HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters
74 REG_SZ/REG_EXPAND_SZ "NetbiosName"
76 If this value is not present, the default is "AFS".
78 When the loopback adapter is not installed the UNC name will be:
80 %COMPUTERNAME%-%NetbiosName%
82 if the Computer Name is "MYHOST" and the Netbios Name is "AFS" then
83 the UNC server name will be:
87 At the moment there is no readily available code exported by a library to
88 determine if the loopback adapter is installed or not. What I will do if
89 someone requests it is add a new AFS pioctl operation which will return
90 the in use UNC Server Name.
93 How to determine the AFS unix mount point path?
95 On Unix systems the local mount point of the AFS file system is usually "/afs".
96 Some organizations have their own custom local mount point locations. To
97 determine what the locally configured unix mount point is for interpretting
98 Unix style paths there is a registry value:
100 HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters
103 If this value does not exist the default value is "/afs".
105 What are AFS pioctl() operations and how do I call them?
107 AFS pioctl() operations are IPCs which can be used to communicate with the
108 AFS Client Service for the purposes of querying or changing the state of
111 The pioctl() function has a prototype of:
120 long pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow);
122 and can be loaded from the library "afsauthent.dll" at runtime. The default
123 calling convention is used.
126 How to test to see if a PATH is within AFS?
128 Given an arbitrary file path, you can test to see if the path is in the AFS
129 file system with the following function. It asks the AFS Client Service to
130 return the name of the cell in which the path exists. If the cell name cannot
131 be found, the path is not in the AFS file space.
133 BOOL IsPathInAFS(const CHAR *strPath)
135 struct ViceIoctl blob;
140 blob.out_size = sizeof(cellname);
143 code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
150 What are AFS cells, volumes and mount points?
152 The AFS file system consists of a series of administrative domains called
153 "cells" each of which contain two or more volumes. A volume is a file system
154 unit which contains files, directories, mount points, symlinks and hard
157 Each cell has a minimum of two volumes. When an AFS client connects to a
158 cell it mounts the cell's "root.afs" volume at the local afs mount point path.
159 Each "root.afs" volume contains one or more mount points which allow the
160 AFS client to other volumes in both in the current cell as well as other
161 cells. There are two types of mount points: read-only and read-write.
162 By following a read-only mount point the client can obtain data from any
163 of the equivalent read-only volume replicas. By following a read-write mount
164 point the client is restricted to the one and only read-write copy of the
165 volume. Periodically replicated volumes have their read-write copy "released"
166 which results in a synchronization with the read-only copies.
168 By convention the first volume of every cell to contain real data is called
169 "root.cell". The name of the read-only mount point which joins the "root.afs"
170 volume to the "root.cell" volume is the name of the cell. The name of the
171 read-write mount point is the name of the cell prefaced by a dot. For
172 example, the "athena.mit.edu" cell's "root.afs" volume will contain mount points
175 "athena.mit.edu" -> "#athena.mit.edu:root.cell"
176 ".athena.mit.edu" -> "%athena.mit.edu:root.cell"
178 The '#' indicates a read-only mount point and the '%' indicates a read-write
179 mount point. The mount points are not limited to the local cell so additional
180 mount points might be included such as:
182 "andrew.cmu.edu" -> "#andrew.cmu.edu:root.cell"
183 "sipb.mit.edu" -> "#sipb.mit.edu:root.cell"
185 The mount points appear as directory entries to the operating system.
187 Volumes can also store files, hard links to files, and symlinks to files.
189 On Windows, hardlinks can be created and destroyed using the CreateHardLink()
190 and DeleteFile() Win32 APIs.
192 Creating, Listing and Destroying symlinks and mount points is performed by
193 the user via the OpenAFS provided command line tools: fs.exe and symlink.exe.
195 symlink make <name> <to>
199 fs mkmount <dir> <vol> [<cell>] [-rw]
203 These operations are performed via pioctl calls.
207 BOOL WhichCell(const char *strPath, char *cell, int len)
209 struct ViceIoctl blob;
216 code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
223 BOOL WorkstationCell(char *cell, int len)
225 struct ViceIoctl blob;
232 code = pioctl(NULL, VIOC_GET_WS_CELL, &blob, 1);
238 /* from afs/afsint.h */
239 struct VolumeStatus {
249 afs_int32 BlocksInUse;
250 afs_int32 PartBlocksAvail;
251 afs_int32 PartMaxBlocks;
253 typedef struct VolumeStatus VolumeStatus;
255 BOOL WhichVolume(const char *strPath, DWORD * volID, char *volname, int len)
257 struct ViceIoctl blob;
259 struct VolumeStatus *status;
260 char *name, *offmsg, *motd;
265 blob.out_size = sizeof(space);
268 code = pioctl(strPath, VIOCGETVOLSTAT, &blob, 1);
272 status = (VolumeStatus *)space;
273 name = (char *)status + sizeof(*status);
274 offmsg = name + strlen(name) + 1;
275 motd = offmsg + strlen(offmsg) + 1;
278 *volID = status->Vid;
281 strncpy(volname, name, len);
282 volname[len-1] = '\0';
285 /* Other items you could grab if you wanted
287 * then there is a message explaining why the volume is offline
290 * then there is a message of the day. (very rarely used)
292 * status->MaxQuota: 0 is unlimited; otherwise 32-bit number of Blocks
293 * status->BlocksInUse: 32-bit number of blocks
294 * status->PartBlocksAvail: 32-bit number of blocks available in
295 * the partition the volume is located on
296 * status->PartMaxBlocks: 32-bit number representing the actual size
299 * These can be used to compute Quota Used, Partition Used, Space Avail,
300 * etc. A block is 1K.
302 * status->Type 0=ReadOnly; 1=ReadWrite
303 * status->Online (boolean)
304 * status->InService (boolean)
305 * status->Blessed (boolean)
306 * status->NeedsSalvage (boolean)
307 * status->ParentId Volume ID of the parent volume. (for readonly)
312 BOOL IsSymlink(const char * dir, const char * entry)
314 struct ViceIoctl blob;
318 blob.in_size = strlen(entry);
320 blob.out_size = sizeof(space);
323 memset(space, 0, sizeof(space));
325 code = pioctl(dir, VIOC_LISTSYMLINK, &blob, 1);
332 BOOL GetSymlink(const char * dir, const char * entry, char * dest, int len)
334 struct ViceIoctl blob;
338 blob.in_size = strlen(entry);
340 blob.out_size = sizeof(space);
343 memset(space, 0, sizeof(space));
345 code = pioctl(dir, VIOC_LISTSYMLINK, &blob, 1);
349 strncpy(dest, space, len);
354 BOOL IsMountPoint(const char * dir, const char * entry)
356 struct ViceIoctl blob;
360 blob.in_size = strlen(entry);
362 blob.out_size = sizeof(space);
365 memset(space, 0, sizeof(space));
367 code = pioctl(dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
374 BOOL GetMountPoint(const char * dir, const char * entry, char * dest, int len)
376 struct ViceIoctl blob;
380 blob.in_size = strlen(entry);
382 blob.out_size = sizeof(space);
385 memset(space, 0, sizeof(space));
387 code = pioctl(dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
391 strncpy(dest, space, len);
396 BOOL IsOnline(const char *strPath)
398 struct ViceIoctl blob;
400 struct VolumeStatus *status;
404 blob.out_size = sizeof(space);
407 code = pioctl(strPath, VIOCGETVOLSTAT, &blob, 1);
411 status = (VolumeStatus *)space;
413 if (!status->Online ||
414 !status->InService ||
416 status->NeedsSalvage)