1
0
Files
2022-09-29 17:59:04 +03:00

313 lines
5.7 KiB
C

/* Copyright 1991 Silicon Graphics, Inc. All rights reserved. */
#if 0
static char sccsid[] = "@(#)prot_libr.c 1.5 91/06/25 NFSSRC4.1 Copyr 1990 Sun Micro";
#endif
/*
* Copyright (c) 1988 by Sun Microsystems, Inc.
*/
/*
* prot_libr.c
* consists of routines used for initialization, mapping and debugging
*/
#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <bstring.h>
#include <netdb.h>
#include <signal.h>
#include <sys/file.h>
#include <sys/fcntl.h>
#include <sys/param.h>
#include "prot_lock.h"
#include "prot_time.h"
#include <rpcsvc/sm_inter.h>
extern int debug;
char hostname[MAXHOSTNAMELEN+1]; /* for generating oh */
int pid; /* id for monitor usage */
int host_len; /* for generating oh */
remote_result res_nolock;
remote_result res_working;
#ifndef SIGLOST
#define SIGLOST SIGUSR1
#endif
static int cookie; /* monitonically increasing # */
init()
{
struct hostent *hp;
(void) gethostname(hostname, sizeof(hostname));
/* canonicalize hostname */
if (hp = gethostbyname(hostname)) {
(void) strncpy(hostname, hp->h_name, sizeof(hostname) -1);
}
/* used to generate owner handle */
host_len = strlen(hostname) +1;
pid = getpid(); /* used to generate return id for status monitor */
res_nolock.lstat = nolocks;
res_working.lstat = blocking;
init_fdtable();
if (sizeof (struct priv_struct) > SM_PRIVLEN) {
syslog(LOG_ERR,
"fatal error: status monitor private data size too big");
exit(1);
}
}
/*
* map input (from kenel) to lock manager internal structure
* returns -1 if cannot allocate memory;
* returns 0 otherwise
*/
int
map_kernel_klm(a)
reclock *a;
{
/*
* common code shared between map_kernel_klm and map_klm_nlm
*/
if (a->lck.lox.length > MAXLEN) {
syslog(LOG_ERR, "len(%d) greater than max len(%d)",
a->lck.lox.length, MAXLEN);
a->lck.lox.length = MAXLEN;
}
/*
* generate svid holder
*/
if (!a->lck.lox.pid)
a->lck.lox.pid = pid;
a->lck.lox.magic = pid;
/*
* owner handle == (hostname, pid);
* cannot generate owner handle use obj_alloc
* because additioanl pid attached at the end
*/
a->lck.oh_len = host_len + sizeof (int);
if ((a->lck.oh_bytes = xmalloc(a->lck.oh_len) ) == NULL)
return (-1);
(void) strcpy(a->lck.oh_bytes, hostname);
bcopy((char *) &a->lck.lox.pid, &a->lck.oh_bytes[host_len],
sizeof (int));
/*
* generate cookie
* cookie is generated from monitonically increasing #
*/
cookie++;
if (obj_alloc(&a->cookie, (char *) &cookie, sizeof (cookie))== -1)
return (-1);
/*
* generate clnt_name
*/
if ((a->lck.clnt_name= xmalloc(host_len)) == NULL)
return (-1);
(void) strcpy(a->lck.clnt_name, hostname);
a->lck.caller_name = a->lck.clnt_name; /* ptr to same area */
return (0);
}
/*
* nlm map input from klm to lock manager internal structure
* return -1, if cannot allocate memory!
* returns 0, otherwise
*/
int
map_klm_nlm(a)
reclock *a;
{
/*
* generate svid holder
*/
if (!a->lck.lox.pid)
a->lck.lox.pid = pid;
a->lck.lox.magic = pid;
/*
* normal klm to nlm calls
*/
a->lck.clnt_name = a->lck.caller_name;
if ((a->lck.server_name = xmalloc(host_len)) == NULL) {
return (-1);
}
(void) strcpy(a->lck.server_name, hostname);
return (0);
}
pr_oh(a)
netobj *a;
{
int i;
int j;
unsigned p = 0;
if (a->n_len == 0) {
printf("(Empty)");
return(0);
}
if (a->n_len - sizeof (int) > 4 )
j = 4;
else
j = a->n_len - sizeof (int);
/*
* only print out part of oh
*/
for (i = 0; i< j; i++) {
printf("%c", a->n_bytes[i]);
}
for (i = a->n_len - sizeof (int); i< a->n_len; i++) {
p = (p << 8) | (((unsigned)a->n_bytes[i]) & 0xff);
}
printf("%u", p);
}
pr_fh(a)
netobj *a;
{
int i;
for (i = 0; i< a->n_len; i++) {
printf("%02x", (a->n_bytes[i] & 0xff));
}
}
static int
getcookie(reclock *a)
{
int i = 0;
if (a->cookie.n_len == 4)
bcopy(a->cookie.n_bytes, &i, sizeof(i));
return i;
}
pr_lock(a)
reclock *a;
{
if (a != NULL) {
printf(" req=%x cuky=%d oh=", a, getcookie(a));
pr_oh(&a->lck.oh);
printf(" svr=%s rel=%d lockID=%d\n",
a->lck.server_name, a->rel, a->lck.lox.LockID);
printf(
" blk=%d excl=%d type=%d baselen=%u,%u pid=%d ipaddr=%x\n",
a->block, a->exclusive, a->lck.lox.type,
a->lck.lox.base, a->lck.lox.length,
a->lck.lox.pid, a->lck.lox.ipaddr);
printf(" fh=");
pr_fh(&a->lck.fh);
printf("\n");
} else {
printf("RECLOCK is NULL.\n");
}
}
pr_all()
{
msg_entry *msgp;
extern msg_entry *msg_q;
if (debug < 2)
return;
/*
* print msg queue
*/
if (msg_q != NULL) {
printf("***** MSG QUEUE *****\n");
msgp= msg_q;
while (msgp != NULL) {
printf("%x=(%x,", msgp,msgp->req);
if (msgp->reply != NULL)
printf(" %s) ",
nlm_stat2name(msgp->reply->lstat));
else
printf(" -) ");
msgp = msgp->nxt;
}
printf("\n");
}
else
printf("***** MSG queue EMPTY *****\n");
(void) fflush(stdout);
}
char *
lck2name(int stat)
{
#ifdef __STDC__
#define F(x) case F_## x : return # x;
#else
#define F(x) case F_/**/x : return "x";
#endif
switch (stat) {
F(RDLCK)
F(WRLCK)
F(UNLCK)
}
return "??";
}
#undef F
char *
klm_stat2name(int stat)
{
#ifdef __STDC__
#define F(x) case klm_## x : return # x;
#else
#define F(x) case klm_/**/x : return "x";
#endif
switch (stat) {
F(granted)
F(denied)
F(denied_nolocks)
F(working)
F(deadlck)
}
return "??";
}
#undef F
char *
nlm_stat2name(int stat)
{
#ifdef __STDC__
#define F(x) case nlm_## x : return # x;
#else
#define F(x) case nlm_/**/x : return "x";
#endif
switch (stat) {
F(granted)
F(denied)
F(denied_nolocks)
F(blocked)
F(denied_grace_period)
F(deadlck)
}
return "??";
}
#undef F
kill_process(a)
reclock *a;
{
syslog(LOG_ERR, "lock not reclaimed, %d killed\n", a->lck.lox.pid);
(void) kill(a->lck.lox.pid, SIGLOST);
}