The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/lockd/mon.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * linux/fs/lockd/mon.c
    3  *
    4  * The kernel statd client.
    5  *
    6  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
    7  */
    8 
    9 #include <linux/types.h>
   10 #include <linux/utsname.h>
   11 #include <linux/kernel.h>
   12 #include <linux/sunrpc/clnt.h>
   13 #include <linux/sunrpc/svc.h>
   14 #include <linux/lockd/lockd.h>
   15 #include <linux/lockd/sm_inter.h>
   16 
   17 
   18 #define NLMDBG_FACILITY         NLMDBG_MONITOR
   19 
   20 static struct rpc_clnt *        nsm_create(void);
   21 
   22 extern struct rpc_program       nsm_program;
   23 
   24 /*
   25  * Local NSM state
   26  */
   27 u32                             nsm_local_state;
   28 
   29 /*
   30  * Common procedure for SM_MON/SM_UNMON calls
   31  */
   32 static int
   33 nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res)
   34 {
   35         struct rpc_clnt *clnt;
   36         int             status;
   37         struct nsm_args args;
   38 
   39         status = -EACCES;
   40         clnt = nsm_create();
   41         if (!clnt)
   42                 goto out;
   43 
   44         args.addr = host->h_addr.sin_addr.s_addr;
   45         args.prog = NLM_PROGRAM;
   46         args.vers = host->h_version;
   47         args.proc = NLMPROC_NSM_NOTIFY;
   48         memset(res, 0, sizeof(*res));
   49 
   50         status = rpc_call(clnt, proc, &args, res, 0);
   51         if (status < 0)
   52                 printk(KERN_DEBUG "nsm_mon_unmon: rpc failed, status=%d\n",
   53                         status);
   54         else
   55                 status = 0;
   56  out:
   57         return status;
   58 }
   59 
   60 /*
   61  * Set up monitoring of a remote host
   62  */
   63 int
   64 nsm_monitor(struct nlm_host *host)
   65 {
   66         struct nsm_res  res;
   67         int             status;
   68 
   69         dprintk("lockd: nsm_monitor(%s)\n", host->h_name);
   70 
   71         status = nsm_mon_unmon(host, SM_MON, &res);
   72 
   73         if (status < 0 || res.status != 0)
   74                 printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name);
   75         else
   76                 host->h_monitored = 1;
   77         return status;
   78 }
   79 
   80 /*
   81  * Cease to monitor remote host
   82  */
   83 int
   84 nsm_unmonitor(struct nlm_host *host)
   85 {
   86         struct nsm_res  res;
   87         int             status;
   88 
   89         dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name);
   90 
   91         status = nsm_mon_unmon(host, SM_UNMON, &res);
   92         if (status < 0)
   93                 printk(KERN_NOTICE "lockd: cannot unmonitor %s\n", host->h_name);
   94         else
   95                 host->h_monitored = 0;
   96         return status;
   97 }
   98 
   99 /*
  100  * Create NSM client for the local host
  101  */
  102 static struct rpc_clnt *
  103 nsm_create(void)
  104 {
  105         struct rpc_xprt         *xprt;
  106         struct rpc_clnt         *clnt = NULL;
  107         struct sockaddr_in      sin;
  108 
  109         sin.sin_family = AF_INET;
  110         sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  111         sin.sin_port = 0;
  112 
  113         xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL);
  114         if (!xprt)
  115                 goto out;
  116 
  117         clnt = rpc_create_client(xprt, "localhost",
  118                                 &nsm_program, SM_VERSION,
  119                                 RPC_AUTH_NULL);
  120         if (!clnt)
  121                 goto out_destroy;
  122         clnt->cl_softrtry = 1;
  123         clnt->cl_chatty   = 1;
  124         clnt->cl_oneshot  = 1;
  125         xprt->resvport = 1;     /* NSM requires a reserved port */
  126 out:
  127         return clnt;
  128 
  129 out_destroy:
  130         xprt_destroy(xprt);
  131         goto out;
  132 }
  133 
  134 /*
  135  * XDR functions for NSM.
  136  */
  137 static int
  138 xdr_error(struct rpc_rqst *rqstp, u32 *p, void *dummy)
  139 {
  140         return -EACCES;
  141 }
  142 
  143 static int
  144 xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
  145 {
  146         char    buffer[20];
  147         u32     addr = ntohl(argp->addr);
  148 
  149         dprintk("nsm: xdr_encode_mon(%08x, %d, %d, %d)\n",
  150                         htonl(argp->addr), htonl(argp->prog),
  151                         htonl(argp->vers), htonl(argp->proc));
  152 
  153         /*
  154          * Use the dotted-quad IP address of the remote host as
  155          * identifier. Linux statd always looks up the canonical
  156          * hostname first for whatever remote hostname it receives,
  157          * so this works alright.
  158          */
  159         sprintf(buffer, "%d.%d.%d.%d", (addr>>24) & 0xff, (addr>>16) & 0xff,
  160                                         (addr>>8) & 0xff,  (addr) & 0xff);
  161         if (!(p = xdr_encode_string(p, buffer))
  162          || !(p = xdr_encode_string(p, system_utsname.nodename)))
  163                 return -EIO;
  164         *p++ = htonl(argp->prog);
  165         *p++ = htonl(argp->vers);
  166         *p++ = htonl(argp->proc);
  167 
  168         /* This is the private part. Needed only for SM_MON call */
  169         if (rqstp->rq_task->tk_msg.rpc_proc == SM_MON) {
  170                 *p++ = argp->addr;
  171                 *p++ = 0;
  172                 *p++ = 0;
  173                 *p++ = 0;
  174         }
  175 
  176         rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p);
  177         return 0;
  178 }
  179 
  180 static int
  181 xdr_decode_stat_res(struct rpc_rqst *rqstp, u32 *p, struct nsm_res *resp)
  182 {
  183         resp->status = ntohl(*p++);
  184         resp->state = ntohl(*p++);
  185         dprintk("nsm: xdr_decode_stat_res status %d state %d\n",
  186                         resp->status, resp->state);
  187         return 0;
  188 }
  189 
  190 static int
  191 xdr_decode_stat(struct rpc_rqst *rqstp, u32 *p, struct nsm_res *resp)
  192 {
  193         resp->state = ntohl(*p++);
  194         return 0;
  195 }
  196 
  197 #define SM_my_name_sz   (1+XDR_QUADLEN(SM_MAXSTRLEN))
  198 #define SM_my_id_sz     (3+1+SM_my_name_sz)
  199 #define SM_mon_id_sz    (1+XDR_QUADLEN(20)+SM_my_id_sz)
  200 #define SM_mon_sz       (SM_mon_id_sz+4)
  201 #define SM_monres_sz    2
  202 #define SM_unmonres_sz  1
  203 
  204 #ifndef MAX
  205 # define MAX(a, b)      (((a) > (b))? (a) : (b))
  206 #endif
  207 
  208 static struct rpc_procinfo      nsm_procedures[] = {
  209         { "sm_null",
  210                 (kxdrproc_t) xdr_error,
  211                 (kxdrproc_t) xdr_error, 0, 0 },
  212         { "sm_stat",
  213                 (kxdrproc_t) xdr_error,
  214                 (kxdrproc_t) xdr_error, 0, 0 },
  215         { "sm_mon",
  216                 (kxdrproc_t) xdr_encode_mon,
  217                 (kxdrproc_t) xdr_decode_stat_res, MAX(SM_mon_sz, SM_monres_sz) << 2, 0 },
  218         { "sm_unmon",
  219                 (kxdrproc_t) xdr_encode_mon,
  220                 (kxdrproc_t) xdr_decode_stat, MAX(SM_mon_id_sz, SM_unmonres_sz) << 2, 0 },
  221         { "sm_unmon_all",
  222                 (kxdrproc_t) xdr_error,
  223                 (kxdrproc_t) xdr_error, 0, 0 },
  224         { "sm_simu_crash",
  225                 (kxdrproc_t) xdr_error,
  226                 (kxdrproc_t) xdr_error, 0, 0 },
  227         { "sm_notify",
  228                 (kxdrproc_t) xdr_error,
  229                 (kxdrproc_t) xdr_error, 0, 0 },
  230 };
  231 
  232 static struct rpc_version       nsm_version1 = {
  233         1, 
  234         sizeof(nsm_procedures)/sizeof(nsm_procedures[0]),
  235         nsm_procedures
  236 };
  237 
  238 static struct rpc_version *     nsm_version[] = {
  239         NULL,
  240         &nsm_version1,
  241 };
  242 
  243 static struct rpc_stat          nsm_stats;
  244 
  245 struct rpc_program              nsm_program = {
  246         "statd",
  247         SM_PROGRAM,
  248         sizeof(nsm_version)/sizeof(nsm_version[0]),
  249         nsm_version,
  250         &nsm_stats
  251 };

Cache object: fbe61c4864d46cbf97b190d32b339519


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.