Annotation of fam/fam/NFSFileSystem.c++, Revision 1.1.1.1
1.1 trev 1: // Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved.
2: //
3: // This program is free software; you can redistribute it and/or modify it
4: // under the terms of version 2 of the GNU General Public License as
5: // published by the Free Software Foundation.
6: //
7: // This program is distributed in the hope that it would be useful, but
8: // WITHOUT ANY WARRANTY; without even the implied warranty of
9: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any
10: // license provided herein, whether implied or otherwise, is limited to
11: // this program in accordance with the express provisions of the GNU
12: // General Public License. Patent licenses, if any, provided herein do not
13: // apply to combinations of this program with other product or programs, or
14: // any other product whatsoever. This program is distributed without any
15: // warranty that the program is delivered free of the rightful claim of any
16: // third person by way of infringement or the like. See the GNU General
17: // Public License for more details.
18: //
19: // You should have received a copy of the GNU General Public License along
20: // with this program; if not, write the Free Software Foundation, Inc., 59
21: // Temple Place - Suite 330, Boston MA 02111-1307, USA.
22:
23: #include "config.h"
24: #include "NFSFileSystem.h"
25:
26: #include <assert.h>
27: #include <mntent.h>
28: #include <stdlib.h>
29: #include <stdio.h>
30: #include <string.h>
31:
32: #include "Log.h"
33: #include "ServerHost.h"
34:
35: #if HAVE_SYS_FS_NFS_CLNT_H
36: #include <rpc/types.h>
37: #include <sys/fs/nfs.h>
38: #include <sys/fs/nfs_clnt.h>
39: #else
40: #define ACREGMAX 60
41: #define ACREGMIN 3
42: #endif
43:
44: NFSFileSystem::NFSFileSystem(const mntent& mnt)
45: : FileSystem(mnt)
46: {
47: // Extract the host name from the fs name.
48:
49: const char *fsname = mnt.mnt_fsname;
50: const char *colon = strchr(fsname, ':');
51: if(colon == NULL)
52: {
53: // shouldn't happen, as this is checked in
54: // FileSystemTable::create_fs_by_name().
55: assert(colon);
56: colon = fsname;
57: }
58: char hostname[NAME_MAX + 1];
59: int hostnamelen = colon - fsname;
60: if(hostnamelen > NAME_MAX)
61: {
62: assert(hostnamelen <= NAME_MAX);
63: hostnamelen = NAME_MAX;
64: }
65: strncpy(hostname, fsname, hostnamelen);
66: hostname[hostnamelen] = '\0';
67:
68: // Look up the host by name.
69:
70: host = ServerHostRef(hostname);
71:
72: // Store the remote directory name. As a special case, "/"
73: // is translated to "" so it will prepend neatly to an absolute
74: // path.
75:
76: const char *dir_part = colon + 1;
77: if (!strcmp(dir_part, "/"))
78: dir_part++;
79: remote_dir_len = strlen(dir_part);
80: remote_dir = strcpy(new char[remote_dir_len + 1], dir_part);
81: local_dir_len = strlen(dir());
82:
83: // Figure out what the attribute cache time is. Look for the
84: // acregmin, acregmax, actimeo, and noac options in the mount
85: // options. Otherwise, use defaults.
86:
87: const char * opt = mnt.mnt_opts;
88:
89: bool f_noac = false;
90: bool f_actimeo = false;
91: bool f_acregmin = false;
92: bool f_acregmax = false;
93:
94: int actimeo;
95: int acregmin;
96: int acregmax;
97:
98: attr_cache_timeout = ACREGMAX;
99:
100: char * p;
101:
102: if (strstr(opt, "noac")) {
103: f_noac = true;
104: }
105: if ((p = strstr(opt, "actimeo")))
106: {
107: if (sscanf(p, "actimeo=%i", &actimeo) == 1) {
108: f_actimeo = true;
109: }
110: }
111:
112: if ((p = strstr(opt, "acregmin"))) {
113: if (sscanf(p, "acregmin=%i", &acregmin) == 1) {
114: f_acregmin = true;
115: }
116: }
117:
118: if ((p = strstr(opt, "acregmax"))) {
119: if (sscanf(p, "acregmax=%i", &acregmax) == 1) {
120: f_acregmax = true;
121: }
122: }
123:
124: if (f_noac) {
125: if (!f_actimeo && !f_acregmin && !f_acregmax) {
126: attr_cache_timeout = 0;
127: } else {
128: Log::error("Both noac and (actimeo, acregmin, or acregmax) "
129: "were set");
130: }
131: } else if (f_actimeo) {
132: if (!f_acregmin && !f_acregmax) {
133: attr_cache_timeout = actimeo;
134: } else {
135: Log::error("Both actimeo and (acregmin or acregmax) were set");
136: }
137: } else if (f_acregmax) {
138: if (f_acregmin) {
139: if (acregmin <= acregmax) {
140: attr_cache_timeout = acregmax;
141: } else {
142: Log::error("Both acregmax and acregmin were set, but "
143: "acregmin was greater than acregmax.");
144: }
145: } else {
146: if (ACREGMIN <= acregmax) {
147: attr_cache_timeout = acregmax;
148: } else {
149: Log::error("acregmax was less than the default for acregmin");
150: }
151: }
152: } else if (f_acregmin) {
153: if (acregmin < ACREGMAX) {
154: attr_cache_timeout = ACREGMAX;
155: } else {
156: attr_cache_timeout = acregmin;
157: }
158: } else {
159: attr_cache_timeout = ACREGMAX;
160: }
161: Log::debug("attr_cache_timout set to %i", attr_cache_timeout);
162: }
163:
164: NFSFileSystem::~NFSFileSystem()
165: {
166: ClientInterest *cip;
167: while ((cip = interests().first()) != NULL)
168: cip->findfilesystem();
169: delete [] remote_dir;
170: }
171:
172: bool
173: NFSFileSystem::dir_entries_scanned() const
174: {
175: return !host->is_connected();
176: }
177:
178:
179: int
180: NFSFileSystem::get_attr_cache_timeout() const
181: {
182: return attr_cache_timeout;
183: }
184:
185: //////////////////////////////////////////////////////////////////////////////
186: // High level interface
187:
188: Request
189: NFSFileSystem::hl_monitor(ClientInterest *ci, ClientInterest::Type type)
190: {
191: const char *path = ci->name();
192: assert(path[0] == '/');
193: char remote_path[PATH_MAX];
194: hl_map_path(remote_path, ci->name(), ci->cred());
195: return host->send_monitor(ci, type, remote_path);
196: }
197:
198: void
199: NFSFileSystem::hl_cancel(Request request)
200: {
201: host->send_cancel(request);
202: }
203:
204: void
205: NFSFileSystem::hl_suspend(Request request)
206: {
207: host->send_suspend(request);
208: }
209:
210: void
211: NFSFileSystem::hl_resume(Request request)
212: {
213: host->send_resume(request);
214: }
215:
216: void
217: NFSFileSystem::hl_map_path(char *remote_path, const char *path, const Cred& cr)
218: {
219: char local_path[PATH_MAX];
220: cr.become_user();
221: if (realpath(path, local_path))
222: { assert(!strncmp(local_path, dir(), local_dir_len));
223: (void) strcpy(remote_path, remote_dir);
224: (void) strcpy(remote_path + remote_dir_len,
225: local_path + local_dir_len);
226: }
227: else
228: {
229: // realpath failed -- remove components one at a time
230: // until it starts succeeding, then append the
231: // missing components to the path. Use remote_path
232: // for scratch space.
233:
234: (void) strcpy(remote_path, path);
235: char *p;
236: do {
237: p = strrchr(remote_path, '/');
238: assert(p);
239: *p = '\0';
240: } while (!realpath(remote_path, local_path));
241: (void) strcpy(remote_path, remote_dir);
242: (void) strcpy(remote_path + remote_dir_len,
243: local_path + local_dir_len);
244: (void) strcat(remote_path, path + (p - remote_path));
245: }
246:
247: // If we're famming a remote machine's root directory, then
248: // remote_path will be empty at this point. Make it "/" instead.
249: if (!*remote_path) {
250: strcpy(remote_path, "/");
251: }
252:
253: // Log::debug("NFSFileSystem::hl_map_path() mapped \"%s\" -> \"%s\"",
254: // path, remote_path);
255: }
256:
257: //////////////////////////////////////////////////////////////////////////////
258: // Low level interface: no implementation.
259:
260: void
261: NFSFileSystem::ll_monitor(Interest *, bool)
262: { }
263:
264: void
265: NFSFileSystem::ll_notify_created(Interest *)
266: { }
267:
268: void
269: NFSFileSystem::ll_notify_deleted(Interest *)
270: { }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>