nfsreaddirres * nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp) { static nfsreaddirres res; static nfsentry e_res[MAX_READDIR_ENTRIES]; am_node *mp; int retry; if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "readdir:"); mp = fh_to_mp3(&argp->rda_fhandle, &retry, VLOOK_CREATE); if (mp == NULL) { if (retry < 0) { amd_stats.d_drops++; return 0; } res.rdr_status = nfs_error(retry); } else { if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path); res.rdr_status = nfs_error((*mp->am_al->al_mnt->mf_ops->readdir) (mp, argp->rda_cookie, &res.rdr_u.rdr_reply_u, e_res, argp->rda_count)); mp->am_stats.s_readdir++; } return &res; }
nfsreadlinkres * nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) { static nfsreadlinkres res; am_node *mp; int retry; if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "readlink:"); mp = fh_to_mp3(argp, &retry, VLOOK_CREATE); if (mp == NULL) { readlink_retry: if (retry < 0) { amd_stats.d_drops++; return 0; } res.rlr_status = nfs_error(retry); } else { char *ln = do_readlink(mp, &retry); if (ln == 0) goto readlink_retry; res.rlr_status = NFS_OK; if (amuDebug(D_TRACE) && ln) plog(XLOG_DEBUG, "\treadlink(%s) = %s", mp->am_path, ln); res.rlr_u.rlr_data_u = ln; mp->am_stats.s_readlink++; } return &res; }
nfsdiropres * nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) { static nfsdiropres res; am_node *mp; int retry; uid_t uid; gid_t gid; if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "lookup:"); /* finally, find the effective uid/gid from RPC request */ if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) plog(XLOG_ERROR, "cannot get uid/gid from RPC credentials"); xsnprintf(opt_uid, sizeof(uid_str), "%d", (int) uid); xsnprintf(opt_gid, sizeof(gid_str), "%d", (int) gid); mp = fh_to_mp3(&argp->da_fhandle, &retry, VLOOK_CREATE); if (mp == NULL) { if (retry < 0) { amd_stats.d_drops++; return 0; } res.dr_status = nfs_error(retry); } else { int error; am_node *ap; if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "\tlookup(%s, %s)", mp->am_path, argp->da_name); ap = mp->am_al->al_mnt->mf_ops->lookup_child(mp, argp->da_name, &error, VLOOK_CREATE); if (ap && error < 0) ap = mp->am_al->al_mnt->mf_ops->mount_child(ap, &error); if (ap == 0) { if (error < 0) { amd_stats.d_drops++; return 0; } res.dr_status = nfs_error(error); } else { /* * XXX: EXPERIMENTAL! Delay unmount of what was looked up. This * should reduce the chance for race condition between unmounting an * entry synchronously, and re-mounting it asynchronously. */ if (ap->am_ttl < mp->am_ttl) ap->am_ttl = mp->am_ttl; mp_to_fh(ap, &res.dr_u.dr_drok_u.drok_fhandle); res.dr_u.dr_drok_u.drok_attributes = ap->am_fattr; res.dr_status = NFS_OK; } mp->am_stats.s_lookup++; /* reschedule_timeout_mp(); */ } return &res; }
nfsstatfsres * nfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) { static nfsstatfsres res; am_node *mp; int retry; mntent_t mnt; if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "statfs:"); mp = fh_to_mp3(argp, &retry, VLOOK_CREATE); if (mp == NULL) { if (retry < 0) { amd_stats.d_drops++; return 0; } res.sfr_status = nfs_error(retry); } else { nfsstatfsokres *fp; if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "\tstat_fs(%s)", mp->am_path); /* * just return faked up file system information */ fp = &res.sfr_u.sfr_reply_u; fp->sfrok_tsize = 1024; fp->sfrok_bsize = 1024; /* check if map is browsable and show_statfs_entries=yes */ if ((gopt.flags & CFM_SHOW_STATFS_ENTRIES) && mp->am_al->al_mnt && mp->am_al->al_mnt->mf_mopts) { mnt.mnt_opts = mp->am_al->al_mnt->mf_mopts; if (amu_hasmntopt(&mnt, "browsable")) { count_map_entries(mp, &fp->sfrok_blocks, &fp->sfrok_bfree, &fp->sfrok_bavail); } } else { fp->sfrok_blocks = 0; /* set to 1 if you don't want empty automounts */ fp->sfrok_bfree = 0; fp->sfrok_bavail = 0; } res.sfr_status = NFS_OK; mp->am_stats.s_statfs++; } return &res; }
bool_t xdr_sattr(XDR *xdrs, nfssattr *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_sattr:"); if (!xdr_u_int(xdrs, &objp->sa_mode)) { return (FALSE); } if (!xdr_u_int(xdrs, &objp->sa_uid)) { return (FALSE); } if (!xdr_u_int(xdrs, &objp->sa_gid)) { return (FALSE); } if (!xdr_u_int(xdrs, &objp->sa_size)) { return (FALSE); } if (!xdr_nfstime(xdrs, &objp->sa_atime)) { return (FALSE); } if (!xdr_nfstime(xdrs, &objp->sa_mtime)) { return (FALSE); } return (TRUE); }
bool_t xdr_writeargs(XDR *xdrs, nfswriteargs *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_writeargs:"); if (!xdr_nfs_fh(xdrs, &objp->wra_fhandle)) { return (FALSE); } if (!xdr_u_int(xdrs, &objp->wra_beginoffset)) { return (FALSE); } if (!xdr_u_int(xdrs, &objp->wra_offset)) { return (FALSE); } if (!xdr_u_int(xdrs, &objp->wra_totalcount)) { return (FALSE); } if (!xdr_bytes(xdrs, (char **) & objp->wra_u.wra_val_u, (u_int *) & objp->wra_u.wra_len_u, NFS_MAXDATA)) { return (FALSE); } return (TRUE); }
voidp xmalloc(int len) { voidp p; int retries = 600; /* * Avoid malloc's which return NULL for malloc(0) */ if (len == 0) len = 1; do { p = (voidp) malloc((unsigned) len); if (p) { #if defined(DEBUG) && defined(DEBUG_MEM) amuDebug(D_MEM) plog(XLOG_DEBUG, "Allocated size %d; block %#x", len, p); #endif /* defined(DEBUG) && defined(DEBUG_MEM) */ return p; } if (retries > 0) { plog(XLOG_ERROR, "Retrying memory allocation"); sleep(1); } } while (--retries); plog(XLOG_FATAL, "Out of memory"); going_down(1); abort(); return 0; }
void unregister_amq(void) { #ifdef DEBUG amuDebug(D_AMQ) #endif /* DEBUG */ /* find which instance of amd to unregister */ pmap_unset(get_amd_program_number(), AMQ_VERSION); }
void dxfree(char *file, int line, voidp ptr) { amuDebug(D_MEM) plog(XLOG_DEBUG, "Free in %s:%d: block %#x", file, line, ptr); /* this is the only place that must NOT use XFREE()!!! */ free(ptr); ptr = NULL; /* paranoid */ }
bool_t xdr_am_filename3(XDR *xdrs, am_filename3 *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_am_filename3:"); if (!xdr_string(xdrs, objp, ~0)) return (FALSE); return (TRUE); }
bool_t xdr_am_nfsstat3(XDR *xdrs, am_nfsstat3 *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_am_nfsstat3:"); if (!xdr_enum(xdrs, (enum_t *)objp)) return (FALSE); return (TRUE); }
bool_t xdr_am_LOOKUP3args(XDR *xdrs, am_LOOKUP3args *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_am_LOOKUP3args:"); if (!xdr_am_diropargs3(xdrs, &objp->what)) return (FALSE); return (TRUE); }
bool_t xdr_mountlist(XDR *xdrs, mountlist *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_mountlist:"); if (!xdr_pointer(xdrs, (char **) objp, sizeof(mountbody), (XDRPROC_T_TYPE) xdr_mountbody)) { return (FALSE); } return (TRUE); }
bool_t xdr_fhandle(XDR *xdrs, fhandle objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_fhandle:"); if (!xdr_opaque(xdrs, objp, NFS_FHSIZE)) { return (FALSE); } return (TRUE); }
bool_t xdr_umntres(XDR *xdrs, umntres *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_mntres:"); if (!xdr_int(xdrs, &objp->status)) return (FALSE); return (TRUE); }
bool_t xdr_groups(XDR *xdrs, groups *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_groups:"); if (!xdr_pointer(xdrs, (char **) objp, sizeof(groupnode), (XDRPROC_T_TYPE) xdr_groupnode)) { return (FALSE); } return (TRUE); }
bool_t xdr_name(XDR *xdrs, name *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_name:"); if (!xdr_string(xdrs, objp, MNTNAMLEN)) { return (FALSE); } return (TRUE); }
bool_t xdr_nfspath(XDR *xdrs, nfspath *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_nfspath:"); if (!xdr_string(xdrs, objp, NFS_MAXPATHLEN)) { return (FALSE); } return (TRUE); }
bool_t xdr_nfscookie(XDR *xdrs, nfscookie objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_nfscookie:"); if (!xdr_opaque(xdrs, objp, NFS_COOKIESIZE)) { return (FALSE); } return (TRUE); }
bool_t xdr_nfs_fh(XDR *xdrs, am_nfs_fh *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_nfs_fh:"); if (!xdr_opaque(xdrs, (caddr_t) objp->fh_data, NFS_FHSIZE)) { return (FALSE); } return (TRUE); }
RETSIGTYPE cleanup(int signum) { struct stat stbuf; int umount_result; if (amuDebug(D_DAEMON)) { if (getpid() != masterpid) return; if (fork() != 0) { masterpid = 0; am_set_mypid(); return; } } am_set_mypid(); for (;;) { while ((umount_result = UMOUNT_FS(dir_name, mnttab_file_name, 0)) == EBUSY) { dlog("cleanup(): umount delaying for 10 seconds"); sleep(10); } if (stat(dir_name, &stbuf) == 0 && stbuf.st_ino == ROOTID) { plog(XLOG_ERROR, "unable to unmount %s", dir_name); plog(XLOG_ERROR, "suspending, unmount before terminating"); kill(am_mypid, SIGSTOP); continue; /* retry unmount */ } break; } if (amuDebug(D_DAEMON)) { plog(XLOG_INFO, "cleanup(): killing processes and terminating"); kill(masterpid, SIGKILL); kill(serverpid, SIGKILL); } plog(XLOG_INFO, "hlfsd terminating with status 0\n"); _exit(0); }
bool_t xdr_am_mountstat3(XDR *xdrs, am_mountstat3 *objp) { enum_t local_obj = *objp; if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_am_mountstat3:"); if (!xdr_enum(xdrs, &local_obj)) return (FALSE); return (TRUE); }
bool_t xdr_am_diropargs3(XDR *xdrs, am_diropargs3 *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_am_diropargs3:"); if (!xdr_am_nfs_fh3(xdrs, &objp->dir)) return (FALSE); if (!xdr_am_filename3(xdrs, &objp->name)) return (FALSE); return (TRUE); }
nfsattrstat * nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) { static nfsattrstat res; am_node *mp; int retry = 0; time_t now = clocktime(NULL); if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "getattr:"); mp = fh_to_mp3(argp, &retry, VLOOK_CREATE); if (mp == NULL) { if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "\tretry=%d", retry); if (retry < 0) { amd_stats.d_drops++; return 0; } res.ns_status = nfs_error(retry); return &res; } res = mp->am_attr; if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "\tstat(%s), size = %d, mtime=%ld.%ld", mp->am_path, (int) res.ns_u.ns_attr_u.na_size, (long) res.ns_u.ns_attr_u.na_mtime.nt_seconds, (long) res.ns_u.ns_attr_u.na_mtime.nt_useconds); /* Delay unmount of what was looked up */ if (mp->am_timeo_w < 4 * gopt.am_timeo_w) mp->am_timeo_w += gopt.am_timeo_w; mp->am_ttl = now + mp->am_timeo_w; mp->am_stats.s_getattr++; return &res; }
bool_t xdr_nfsstat(XDR *xdrs, nfsstat *objp) { enum_t local_obj = *objp; if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_nfsstat:"); if (!xdr_enum(xdrs, &local_obj)) { return (FALSE); } return (TRUE); }
bool_t xdr_umntres(XDR *xdrs, umntres *objp) { #ifdef DEBUG amuDebug(D_XDRTRACE) plog(XLOG_DEBUG, "xdr_mntres:"); #endif /* DEBUG */ if (!xdr_int(xdrs, &objp->status)) return (FALSE); return (TRUE); }
void unregister_amq(void) { if (amuDebug(D_AMQ)) { /* find which instance of amd to unregister */ u_long amd_prognum = get_amd_program_number(); if (pmap_unset(amd_prognum, AMQ_VERSION) != 1) dlog("failed to de-register Amd program %lu, version %lu", amd_prognum, AMQ_VERSION); } }
bool_t xdr_am_fhandle3(XDR *xdrs, am_fhandle3 *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_am_fhandle3:"); if (!xdr_bytes(xdrs, (char **) &objp->fhandle3_val, (u_int *) &objp->fhandle3_len, AM_FHSIZE3)) return (FALSE); return (TRUE); }
bool_t xdr_sattrargs(XDR *xdrs, nfssattrargs *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_sattrargs:"); if (!xdr_nfs_fh(xdrs, &objp->sag_fhandle)) { return (FALSE); } if (!xdr_sattr(xdrs, &objp->sag_attributes)) { return (FALSE); } return (TRUE); }
bool_t xdr_dirlist(XDR *xdrs, nfsdirlist *objp) { if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_dirlist:"); if (!xdr_pointer(xdrs, (char **) &objp->dl_entries, sizeof(nfsentry), (XDRPROC_T_TYPE) xdr_entry)) { return (FALSE); } if (!xdr_bool(xdrs, &objp->dl_eof)) { return (FALSE); } return (TRUE); }