[BACK]Return to NFSFileSystem.c++ CVS log [TXT][DIR] Up to [Development] / fam / fam

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>