1 ...(This document is current as of release 1.5.55)
3 How to determine if OpenAFS is installed?
5 When the OpenAFS Client Service is installed there will be several
8 HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon
9 "ImagePath" = "path to afsd_service.exe"
11 HKLM\SOFTWARE\TransarcCorporation\AFS Client\CurrentVersion
12 "PathName" = "the path to the client installation directory"
17 BOOL IsAFSServerInstalled (void)
19 BOOL fInstalled = FALSE;
20 TCHAR szKey[] = TEXT("HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon");
21 LPCTSTR pch = lstrchr (szKey, TEXT('\\'));
24 if (RegOpenKey (HKEY_LOCAL_MACHINE, &pch[1], &hk) == 0)
33 How to determine if OpenAFS is active?
35 The AFS Client Service is normally started automatically at system boot.
36 The state of the service may be queried by asking the Windows Service
39 BOOL IsAFSServiceRunning (void)
41 SERVICE_STATUS Status;
42 memset (&Status, 0x00, sizeof(Status));
43 Status.dwCurrentState = SERVICE_STOPPED;
46 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
49 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
51 QueryServiceStatus (hService, &Status);
52 CloseServiceHandle (hService);
54 CloseServiceHandle (hManager);
56 return (Status.dwCurrentState == SERVICE_RUNNING);
59 How to determine the AFS UNC Service Name?
61 The local UNC service name registered by the OpenAFS Client Service SMB/CIFS
62 Server depends on whether or not a Microsoft Loopback Adapter has been
63 installed and the contents of a registry value. The loopback adapter is
64 important because if the service cannot bind itself to a loopback adapter
65 then the registered SMB/CIFS service name must be unique to the WINS name
66 space. When the loopback adapter is installed, a globally common name such
69 If the loopback adapter is installed the UNC server name will be the value at:
71 HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters
72 REG_SZ/REG_EXPAND_SZ "NetbiosName"
74 If this value is not present, the default is "AFS".
76 When the loopback adapter is not installed the UNC name will be:
78 %COMPUTERNAME%-%NetbiosName%
80 if the Computer Name is "MYHOST" and the Netbios Name is "AFS" then
81 the UNC server name will be:
85 At the moment there is no readily available code exported by a library to
86 determine if the loopback adapter is installed or not. What I will do if
87 someone requests it is add a new AFS pioctl operation which will return
88 the in use UNC Server Name.
91 How to determine the AFS unix mount point path?
93 On Unix systems the local mount point of the AFS file system is usually "/afs".
94 Some organizations have their own custom local mount point locations. To
95 determine what the locally configured unix mount point is for interpretting
96 Unix style paths there is a registry value:
98 HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters
101 If this value does not exist the default value is "/afs".
103 What are AFS pioctl() operations and how do I call them?
105 AFS pioctl() operations are IPCs which can be used to communicate with the
106 AFS Client Service for the purposes of querying or changing the state of
109 The pioctl() function has a prototype of:
118 long pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow);
120 and can be loaded from the library "afsauthent.dll" at runtime. The default
121 calling convention is used.
124 How to test to see if a PATH is within AFS?
126 Given an arbitrary file path, you can test to see if the path is in the AFS
127 file system with the following function. It asks the AFS Client Service to
128 return the name of the cell in which the path exists. If the cell name cannot
129 be found, the path is not in the AFS file space.
131 BOOL IsPathInAFS(const CHAR *strPath)
133 struct ViceIoctl blob;
138 blob.out_size = sizeof(cellname);
141 code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
148 What are AFS cells, volumes and mount points?
150 The AFS file system consists of a series of administrative domains called
151 "cells" each of which contain two or more volumes. A volume is a file system
152 unit which contains files, directories, mount points, symlinks and hard
155 Each cell has a minimum of two volumes. When an AFS client connects to a
156 cell it mounts the cell's "root.afs" volume at the local afs mount point path.
157 Each "root.afs" volume contains one or more mount points which allow the
158 AFS client to other volumes in both in the current cell as well as other
159 cells. There are two types of mount points: read-only and read-write.
160 By following a read-only mount point the client can obtain data from any
161 of the equivalent read-only volume replicas. By following a read-write mount
162 point the client is restricted to the one and only read-write copy of the
163 volume. Periodically replicated volumes have their read-write copy "released"
164 which results in a synchronization with the read-only copies.
166 By convention the first volume of every cell to contain real data is called
167 "root.cell". The name of the read-only mount point which joins the "root.afs"
168 volume to the "root.cell" volume is the name of the cell. The name of the
169 read-write mount point is the name of the cell prefaced by a dot. For
170 example, the "athena.mit.edu" cell's "root.afs" volume will contain mount points
173 "athena.mit.edu" -> "#athena.mit.edu:root.cell"
174 ".athena.mit.edu" -> "%athena.mit.edu:root.cell"
176 The '#' indicates a read-only mount point and the '%' indicates a read-write
177 mount point. The mount points are not limited to the local cell so additional
178 mount points might be included such as:
180 "andrew.cmu.edu" -> "#andrew.cmu.edu:root.cell"
181 "sipb.mit.edu" -> "#sipb.mit.edu:root.cell"
183 The mount points appear as directory entries to the operating system.
185 Volumes can also store files, hard links to files, and symlinks to files.
187 On Windows, hardlinks can be created and destroyed using the CreateHardLink()
188 and DeleteFile() Win32 APIs.
190 Creating, Listing and Destroying symlinks and mount points is performed by
191 the user via the OpenAFS provided command line tools: fs.exe and symlink.exe.
193 symlink make <name> <to>
197 fs mkmount <dir> <vol> [<cell>] [-rw]
201 These operations are performed via pioctl calls.
205 BOOL WhichCell(const char *strPath, char *cell, int len)
207 struct ViceIoctl blob;
214 code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
221 BOOL WorkstationCell(char *cell, int len)
223 struct ViceIoctl blob;
230 code = pioctl(NULL, VIOC_GET_WS_CELL, &blob, 1);
236 /* from afs/afsint.h */
237 struct VolumeStatus {
247 afs_int32 BlocksInUse;
248 afs_int32 PartBlocksAvail;
249 afs_int32 PartMaxBlocks;
251 typedef struct VolumeStatus VolumeStatus;
253 BOOL WhichVolume(const char *strPath, DWORD * volID, char *volname, int len)
255 struct ViceIoctl blob;
257 struct VolumeStatus *status;
258 char *name, *offmsg, *motd;
263 blob.out_size = sizeof(space);
266 code = pioctl(strPath, VIOCGETVOLSTAT, &blob, 1);
270 status = (VolumeStatus *)space;
271 name = (char *)status + sizeof(*status);
272 offmsg = name + strlen(name) + 1;
273 motd = offmsg + strlen(offmsg) + 1;
276 *volID = status->Vid;
279 strncpy(volname, name, len);
280 volname[len-1] = '\0';
283 /* Other items you could grab if you wanted
285 * then there is a message explaining why the volume is offline
288 * then there is a message of the day. (very rarely used)
290 * status->MaxQuota: 0 is unlimited; otherwise 32-bit number of Blocks
291 * status->BlocksInUse: 32-bit number of blocks
292 * status->PartBlocksAvail: 32-bit number of blocks available in
293 * the partition the volume is located on
294 * status->PartMaxBlocks: 32-bit number representing the actual size
297 * These can be used to compute Quota Used, Partition Used, Space Avail,
298 * etc. A block is 1K.
300 * status->Type 0=ReadOnly; 1=ReadWrite
301 * status->Online (boolean)
302 * status->InService (boolean)
303 * status->Blessed (boolean)
304 * status->NeedsSalvage (boolean)
305 * status->ParentId Volume ID of the parent volume. (for readonly)
310 BOOL IsSymlink(const char * dir, const char * entry)
312 struct ViceIoctl blob;
316 blob.in_size = strlen(entry);
318 blob.out_size = sizeof(space);
321 memset(space, 0, sizeof(space));
323 code = pioctl(dir, VIOC_LISTSYMLINK, &blob, 1);
330 BOOL GetSymlink(const char * dir, const char * entry, char * dest, int len)
332 struct ViceIoctl blob;
336 blob.in_size = strlen(entry);
338 blob.out_size = sizeof(space);
341 memset(space, 0, sizeof(space));
343 code = pioctl(dir, VIOC_LISTSYMLINK, &blob, 1);
347 strncpy(dest, space, len);
352 BOOL IsMountPoint(const char * dir, const char * entry)
354 struct ViceIoctl blob;
358 blob.in_size = strlen(entry);
360 blob.out_size = sizeof(space);
363 memset(space, 0, sizeof(space));
365 code = pioctl(dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
372 BOOL GetMountPoint(const char * dir, const char * entry, char * dest, int len)
374 struct ViceIoctl blob;
378 blob.in_size = strlen(entry);
380 blob.out_size = sizeof(space);
383 memset(space, 0, sizeof(space));
385 code = pioctl(dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
389 strncpy(dest, space, len);
394 BOOL IsOnline(const char *strPath)
396 struct ViceIoctl blob;
398 struct VolumeStatus *status;
402 blob.out_size = sizeof(space);
405 code = pioctl(strPath, VIOCGETVOLSTAT, &blob, 1);
409 status = (VolumeStatus *)space;
411 if (!status->Online ||
412 !status->InService ||
414 status->NeedsSalvage)