/** * getfh - ask the kernel for an NFSv2 file handle via nfsctl() * @sin: pointer to IPv4 address of a client * @path: pointer to a '\0'-terminated ASCII string containing an pathname * * Returns a pointer to an NFSv2 file handle, or NULL if some error * occurred. errno is set to reflect the specifics of the error. */ struct nfs_fh_len * getfh(const struct sockaddr_in *sin, const char *path) { static union nfsctl_res res; struct nfsctl_arg arg; static struct nfs_fh_len rfh; if (sin->sin_family != AF_INET) { errno = EAFNOSUPPORT; return NULL; } memset(&arg, 0, sizeof(arg)); memset(&res, 0, sizeof(res)); arg.ca_version = NFSCTL_VERSION; arg.ca_getfd.gd_version = 2; /* obsolete */ strncpy(arg.ca_getfd.gd_path, path, sizeof(arg.ca_getfd.gd_path) - 1); arg.ca_getfd.gd_path[sizeof (arg.ca_getfd.gd_path) - 1] = '\0'; memcpy(&arg.ca_getfd.gd_addr, sin, sizeof(*sin)); if (nfsctl(NFSCTL_GETFD, &arg, &res) < 0) return NULL; memset(&rfh, 0, sizeof(rfh)); rfh.fh_size = 32; memcpy(rfh.fh_handle, &res.cr_getfh, 32); return &rfh; }
/** * getfh_old - ask the kernel for an NFSv2 file handle via nfsctl() * @sin: pointer to IPv4 address of a client * @dev: device number of device where requested object resides * @ino: inode number of requested object * * Returns a pointer to an NFSv2 file handle, or NULL if some error * occurred. errno is set to reflect the specifics of the error. */ struct nfs_fh_len * getfh_old(const struct sockaddr_in *sin, const dev_t dev, const ino_t ino) { union nfsctl_res res; struct nfsctl_arg arg; static struct nfs_fh_len rfh; if (sin->sin_family != AF_INET) { errno = EAFNOSUPPORT; return NULL; } memset(&arg, 0, sizeof(arg)); memset(&res, 0, sizeof(res)); arg.ca_version = NFSCTL_VERSION; arg.ca_getfh.gf_version = 2; /* obsolete */ arg.ca_getfh.gf_dev = dev; arg.ca_getfh.gf_ino = ino; memcpy(&arg.ca_getfh.gf_addr, sin, sizeof(*sin)); if (nfsctl(NFSCTL_GETFH, &arg, &res) < 0) return NULL; memset(&rfh, 0, sizeof(rfh)); rfh.fh_size = 32; memcpy(rfh.fh_handle, &res.cr_getfh, 32); return &rfh; }
/** * getfh_size - ask the kernel for a file handle via nfsctl() * @sin: pointer to IPv4 address of a client * @path: pointer to a '\0'-terminated ASCII string containing an pathname * @size: maximum size, in bytes, of the returned file handle * * Returns a pointer to an NFSv3 file handle, or NULL if some error * occurred. errno is set to reflect the specifics of the error. */ struct nfs_fh_len * getfh_size(const struct sockaddr_in *sin, const char *path, const int size) { static union nfsctl_res res; struct nfsctl_arg arg; if (sin->sin_family != AF_INET) { errno = EAFNOSUPPORT; return NULL; } memset(&arg, 0, sizeof(arg)); memset(&res, 0, sizeof(res)); arg.ca_version = NFSCTL_VERSION; strncpy(arg.ca_getfs.gd_path, path, sizeof(arg.ca_getfs.gd_path) - 1); arg.ca_getfs.gd_path[sizeof (arg.ca_getfs.gd_path) - 1] = '\0'; memcpy(&arg.ca_getfs.gd_addr, sin, sizeof(*sin)); arg.ca_getfs.gd_maxlen = size; if (nfsctl(NFSCTL_GETFS, &arg, &res) < 0) return NULL; return &res.cr_getfs; }
int lockdsvc() { struct nfsctl_arg arg; arg.ca_version = NFSCTL_VERSION; return nfsctl(LOCKDCTL_SVC, &arg, NULL); }
struct nfs_fh_len * getfh_size(struct sockaddr *addr, const char *path, int size) { static union nfsctl_res res; struct nfsctl_arg arg; arg.ca_version = NFSCTL_VERSION; strncpy(arg.ca_getfs.gd_path, path, sizeof(arg.ca_getfs.gd_path) - 1); arg.ca_getfs.gd_path[sizeof (arg.ca_getfs.gd_path) - 1] = '\0'; memcpy(&arg.ca_getfs.gd_addr, addr, sizeof(struct sockaddr_in)); arg.ca_getfs.gd_maxlen = size; if (nfsctl(NFSCTL_GETFS, &arg, &res) < 0) return NULL; return &res.cr_getfs; }
struct nfs_fh_len * getfh_old (struct sockaddr *addr, dev_t dev, ino_t ino) { union nfsctl_res res; struct nfsctl_arg arg; static struct nfs_fh_len rfh; arg.ca_version = NFSCTL_VERSION; arg.ca_getfh.gf_version = 2; /* obsolete */ arg.ca_getfh.gf_dev = dev; arg.ca_getfh.gf_ino = ino; memcpy(&arg.ca_getfh.gf_addr, addr, sizeof(struct sockaddr_in)); if (nfsctl(NFSCTL_GETFH, &arg, &res) < 0) return NULL; rfh.fh_size = 32; memcpy(rfh.fh_handle, &res.cr_getfh, 32); return &rfh; }
struct nfs_fh_len * getfh(struct sockaddr *addr, const char *path) { static union nfsctl_res res; struct nfsctl_arg arg; static struct nfs_fh_len rfh; arg.ca_version = NFSCTL_VERSION; arg.ca_getfd.gd_version = 2; /* obsolete */ strncpy(arg.ca_getfd.gd_path, path, sizeof(arg.ca_getfd.gd_path) - 1); arg.ca_getfd.gd_path[sizeof (arg.ca_getfd.gd_path) - 1] = '\0'; memcpy(&arg.ca_getfd.gd_addr, addr, sizeof(struct sockaddr_in)); if (nfsctl(NFSCTL_GETFD, &arg, &res) < 0) return NULL; rfh.fh_size = 32; memcpy(rfh.fh_handle, &res.cr_getfh, 32); return &rfh; }
int nfssvc_threads(unsigned short port, const int nrservs) { struct nfsctl_arg arg; struct servent *ent; ssize_t n; int fd; fd = open(NFSD_THREAD_FILE, O_WRONLY); if (fd < 0) fd = open("/proc/fs/nfs/threads", O_WRONLY); if (fd >= 0) { /* 2.5+ kernel with nfsd filesystem mounted. * Just write the number of threads. */ snprintf(buf, sizeof(buf), "%d\n", nrservs); n = write(fd, buf, strlen(buf)); close(fd); if (n != (ssize_t)strlen(buf)) return -1; else return 0; } if (!port) { ent = getservbyname("nfs", "udp"); if (ent != NULL) port = ntohs(ent->s_port); else port = NFS_PORT; } arg.ca_version = NFSCTL_VERSION; arg.ca_svc.svc_nthreads = nrservs; arg.ca_svc.svc_port = port; return nfsctl(NFSCTL_SVC, &arg, NULL); }