Annotation of fam/fam/NFSFileSystem.c++, Revision 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>