rpc.rquotad.c revision edea4b556f0b07459cdcc780ffcd28a40b374945
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
#include <string.h>
#include <stropts.h>
#include <errno.h>
#include <sys/netconfig.h>
#ifdef notdef
#include <netconfig.h>
#endif
#include <netdir.h>
#include <tiuser.h>
#include <unistd.h>
#include <dlfcn.h>
#include <libzfs.h>
struct fsquot {
char *fsq_fstype;
char *fsq_dir;
char *fsq_devname;
};
typedef struct authunix_parms *authp;
static int request_pending; /* Request in progress ? */
void closedown();
void dispatch();
void freefs();
int getdiskquota();
void getquota();
int hasquota();
void log_cant_reply();
void setupfs();
static void zexit();
static libzfs_handle_t *(*_libzfs_init)(void);
static void (*_libzfs_fini)(libzfs_handle_t *);
static void (*_zfs_close)(zfs_handle_t *);
static int (*_zfs_prop_get_userquota_int)(zfs_handle_t *, const char *,
uint64_t *);
/*
* Dynamically check for libzfs, in case the user hasn't installed the SUNWzfs
* packages. 'rquotad' supports zfs as an option.
*/
static void
load_libzfs(void)
{
void *hdl;
return;
"libzfs_init");
_zfs_prop_get_userquota_int = (int (*)())
g_zfs = _libzfs_init();
}
}
/*ARGSUSED*/
int
{
load_libzfs();
/*
* If stdin looks like a TLI endpoint, we assume
* that we were started by a port monitor. If
* t_getstate fails with TBADF, this is not a
* TLI endpoint.
*/
char *netid;
if (t_sync(0) == -1) {
zexit(1);
}
zexit(1);
}
netid = "udp";
else
netid = "udp6";
} else {
zexit(1);
}
}
}
zexit(1);
}
if (nconf)
"unable to register (RQUOTAPROG, RQUOTAVERS).");
zexit(1);
}
(void) alarm(RPCSVC_CLOSEDOWN);
svc_run();
zexit(1);
/* NOTREACHED */
}
/*
* Started from a shell - fork the daemon.
*/
switch (fork()) {
case 0: /* child */
break;
case -1:
perror("rquotad: can't fork");
zexit(1);
default: /* parent */
zexit(0);
}
/*
* standard input, output, and error, and detach from
* controlling terminal.
*/
closefrom(0);
(void) dup(1);
(void) setsid();
/*
* Create datagram service
*/
zexit(1);
}
/*
* Start serving
*/
svc_run();
return (1);
}
void
{
request_pending = 1;
case NULLPROC:
errno = 0;
break;
case RQUOTAPROC_GETQUOTA:
break;
default:
break;
}
request_pending = 0;
}
void
{
if (!request_pending) {
int i, openfd;
zexit(0);
if (svc_pollfd[i].fd >= 0)
openfd++;
}
if (openfd <= 1)
zexit(0);
}
(void) alarm(RPCSVC_CLOSEDOWN);
}
static int
{
char propname[ZFS_MAXPROPLEN];
return (1);
return (1);
}
return (1);
}
return (1);
}
return (0);
}
void
{
struct getquota_args gqa;
struct getquota_rslt gqr;
return;
}
/*
* This authentication is really bogus with the current rpc
* authentication scheme. One day we will have something for real.
*/
goto sendreply;
}
goto sendreply;
}
goto sendreply;
}
} else {
goto sendreply;
}
/*
* If there is no quotas file, don't bother to sync it.
*/
"Quotas are not compiled "
"into this kernel");
&dqblk) == 0) {
goto sendreply;
}
}
} else {
}
/*
* We send the remaining time instead of the absolute time
* because clock skew between machines should be much greater
* than rpc delay.
*/
}
errno = 0;
}
int
int cmd;
char *mountp;
{
int fd;
int status;
char mountpoint[256];
/*
* Find the mount point of any ufs file system. this is
* because the ioctl that implements the quotactl call has
* to go to a real file, and not to the block device.
*/
return (-1);
}
fd = -1;
continue;
sizeof (mountpoint));
break;
}
if (fd == -1) {
return (-1);
}
} else {
return (-1);
}
return (-1);
}
}
return (status);
}
/*
* Return the quota information for the given path. Returns NULL if none
* was found.
*/
struct fsquot *
char *dir;
{
/*
* If we've never looked at the mount table, or it has changed
* since the last time, rebuild the list of quota'd file systems
* and remember the current mod time for the mount table.
*/
return (NULL);
}
freefs();
setupfs();
}
/*
* Try to find the given path in the list of file systems with
* quotas.
*/
return (NULL);
return (NULL);
return (fsqp);
return (fsqp);
}
}
return (NULL);
}
static void
{
zexit(1);
}
zexit(1);
}
}
void
setupfs()
{
struct mnttab m;
char qfilename[MAXPATHLEN];
return;
}
setup_zfs(&m);
continue;
}
continue;
if (!hasquota(m.mnt_mntopts)) {
m.mnt_mountp, QFNAME);
continue;
}
continue;
zexit(1);
}
zexit(1);
}
}
}
/*
* Free the memory used by the current list of quota'd file systems. Nulls
* out the list.
*/
void
freefs()
{
}
}
int
{
int fd;
char qfilename[MAXPATHLEN];
return (0);
return (0);
}
return (0);
}
return (1);
}
/*
* Get the client's hostname from the transport handle
* If the name is not available then return "(anon)".
*/
struct nd_hostservlist *
{
static struct nd_hostservlist *serv;
static struct nd_hostservlist anon_hsl;
static struct nd_hostserv anon_hs;
static char anon_hname[] = "(anon)";
static char anon_sname[] = "";
/* Set up anonymous client */
if (serv) {
}
return (&anon_hsl);
}
return (&anon_hsl);
}
return (&anon_hsl);
}
return (serv);
}
void
{
int saverrno;
struct nd_hostservlist *clnames;
register char *name;
return;
if (errno == 0)
else
}
#define QUOTA 0
/*
* Return 1 if "quota" appears in the options string
*/
int
char *opts;
{
char *value;
return (0);
while (*opts != '\0') {
return (1);
}
return (0);
}
static void
zexit(int n)
{
exit(n);
}