Cleanup.
use LIST_FOREACH, add prototypes (functions should be made static probably), change DEBUG=1 to LOCKD_DEBUG, K&R function instantiation for functions with long args lists, Move comments about functions from within to above the function, Simplified some if/else logic and reduced nested blocks. parens around 'return' argument (return FOO -> return (FOO))
This commit is contained in:
parent
a4a8a04d08
commit
b6dc41baf1
@ -35,10 +35,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DEBUG 1
|
#define LOCKD_DEBUG
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef DEBUG
|
#ifdef LOCKD_DEBUG
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -144,6 +144,9 @@ enum hwlock_status { HW_GRANTED = 0, HW_GRANTED_DUPLICATE,
|
|||||||
HW_DENIED, HW_DENIED_NOLOCK,
|
HW_DENIED, HW_DENIED_NOLOCK,
|
||||||
HW_STALEFH, HW_READONLY, HW_RESERR };
|
HW_STALEFH, HW_READONLY, HW_RESERR };
|
||||||
|
|
||||||
|
enum split_status {SPL_DISJOINT, SPL_LOCK_CONTAINED, SPL_LOCK_LEFT,
|
||||||
|
SPL_LOCK_RIGHT, SPL_UNLOCK_CONTAINED};
|
||||||
|
|
||||||
enum partialfilelock_status { PFL_GRANTED=0, PFL_GRANTED_DUPLICATE, PFL_DENIED,
|
enum partialfilelock_status { PFL_GRANTED=0, PFL_GRANTED_DUPLICATE, PFL_DENIED,
|
||||||
PFL_NFSDENIED, PFL_NFSBLOCKED, PFL_NFSDENIED_NOLOCK, PFL_NFSRESERR,
|
PFL_NFSDENIED, PFL_NFSBLOCKED, PFL_NFSDENIED_NOLOCK, PFL_NFSRESERR,
|
||||||
PFL_HWDENIED, PFL_HWBLOCKED, PFL_HWDENIED_NOLOCK, PFL_HWRESERR};
|
PFL_HWDENIED, PFL_HWBLOCKED, PFL_HWDENIED_NOLOCK, PFL_HWRESERR};
|
||||||
@ -156,6 +159,52 @@ void sigunlock(void);
|
|||||||
void monitor_lock_host(const char *hostname);
|
void monitor_lock_host(const char *hostname);
|
||||||
void unmonitor_lock_host(const char *hostname);
|
void unmonitor_lock_host(const char *hostname);
|
||||||
|
|
||||||
|
void copy_nlm4_lock_to_nlm4_holder(const struct nlm4_lock *src,
|
||||||
|
const bool_t exclusive, struct nlm4_holder *dest);
|
||||||
|
void deallocate_file_lock(struct file_lock *fl);
|
||||||
|
int regions_overlap(const u_int64_t start1, const u_int64_t len1,
|
||||||
|
const u_int64_t start2, const u_int64_t len2);;
|
||||||
|
int same_netobj(const netobj *n0, const netobj *n1);
|
||||||
|
int same_filelock_identity(const struct file_lock *fl0,
|
||||||
|
const struct file_lock *fl2);
|
||||||
|
|
||||||
|
static void debuglog(char const *fmt, ...);
|
||||||
|
void dump_static_object(const unsigned char* object, const int sizeof_object,
|
||||||
|
unsigned char* hbuff, const int sizeof_hbuff,
|
||||||
|
unsigned char* cbuff, const int sizeof_cbuff);
|
||||||
|
void dump_netobj(const struct netobj *nobj);
|
||||||
|
void dump_filelock(const struct file_lock *fl);
|
||||||
|
struct file_lock * malloccopy_filelock(struct file_lock *fl);
|
||||||
|
struct file_lock * get_lock_matching_unlock(const struct file_lock *fl);
|
||||||
|
enum nfslock_status test_nfslock(const struct file_lock *fl,
|
||||||
|
struct file_lock **conflicting_fl);
|
||||||
|
enum nfslock_status lock_nfslock(struct file_lock *fl);
|
||||||
|
enum nfslock_status delete_nfslock(struct file_lock *fl);
|
||||||
|
enum nfslock_status unlock_nfslock(const struct file_lock *fl,
|
||||||
|
struct file_lock **released_lock, struct file_lock *left_lock,
|
||||||
|
struct file_lock *right_lock);
|
||||||
|
enum hwlock_status lock_hwlock(struct file_lock *fl);
|
||||||
|
enum split_status split_nfslock(const struct file_lock *exist_lock,
|
||||||
|
const struct file_lock *unlock_lock, const struct file_lock *right_lock);
|
||||||
|
void add_blockingfilelock(struct file_lock *fl);
|
||||||
|
enum hwlock_status unlock_hwlock(const struct file_lock *fl);
|
||||||
|
enum hwlock_status test_hwlock(const struct file_lock *fl,
|
||||||
|
struct file_lock **conflicting_fl);
|
||||||
|
void remove_blockingfilelock(struct file_lock *fl);
|
||||||
|
void clear_blockingfilelock(const char *hostname);
|
||||||
|
void retry_blockingfilelocklist(void);
|
||||||
|
enum partialfilelock_status unlock_partialfilelock(
|
||||||
|
const struct file_lock *fl);
|
||||||
|
void clear_partialfilelock(const char *hostname);
|
||||||
|
enum partialfilelock_status test_partialfilelock(
|
||||||
|
const struct file_lock *fl, struct file_lock **conflicting_fl);
|
||||||
|
enum nlm_stats do_test(struct file_lock *fl,
|
||||||
|
struct file_lock **conflicting_fl);
|
||||||
|
enum nlm_stats do_unlock(struct file_lock *fl);
|
||||||
|
enum nlm_stats do_lock(struct file_lock *fl);
|
||||||
|
void do_clear(const char *hostname);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
debuglog(char const *fmt, ...)
|
debuglog(char const *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -172,17 +221,22 @@ debuglog(char const *fmt, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_static_object(const unsigned char* object, const int sizeof_object,
|
void
|
||||||
unsigned char* hbuff, const int sizeof_hbuff,
|
dump_static_object(object, size_object, hbuff, size_hbuff, cbuff, size_cbuff)
|
||||||
unsigned char* cbuff, const int sizeof_cbuff)
|
const unsigned char *object;
|
||||||
|
const int size_object;
|
||||||
|
unsigned char *hbuff;
|
||||||
|
const int size_hbuff;
|
||||||
|
unsigned char *cbuff;
|
||||||
|
const int size_cbuff;
|
||||||
{
|
{
|
||||||
int i,objectsize;
|
int i, objectsize;
|
||||||
|
|
||||||
if (debug_level < 2) {
|
if (debug_level < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
objectsize = sizeof_object;
|
objectsize = size_object;
|
||||||
|
|
||||||
if (objectsize == 0) {
|
if (objectsize == 0) {
|
||||||
debuglog("object is size 0\n");
|
debuglog("object is size 0\n");
|
||||||
@ -194,7 +248,7 @@ void dump_static_object(const unsigned char* object, const int sizeof_object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hbuff != NULL) {
|
if (hbuff != NULL) {
|
||||||
if (sizeof_hbuff < objectsize*2+1) {
|
if (size_hbuff < objectsize*2+1) {
|
||||||
debuglog("Hbuff not large enough."
|
debuglog("Hbuff not large enough."
|
||||||
" Increase size\n");
|
" Increase size\n");
|
||||||
} else {
|
} else {
|
||||||
@ -206,7 +260,7 @@ void dump_static_object(const unsigned char* object, const int sizeof_object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cbuff != NULL) {
|
if (cbuff != NULL) {
|
||||||
if (sizeof_cbuff < objectsize+1) {
|
if (size_cbuff < objectsize+1) {
|
||||||
debuglog("Cbuff not large enough."
|
debuglog("Cbuff not large enough."
|
||||||
" Increase Size\n");
|
" Increase Size\n");
|
||||||
}
|
}
|
||||||
@ -223,7 +277,8 @@ void dump_static_object(const unsigned char* object, const int sizeof_object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_netobj(const struct netobj *nobj)
|
void
|
||||||
|
dump_netobj(const struct netobj *nobj)
|
||||||
{
|
{
|
||||||
char hbuff[MAXBUFFERSIZE*2];
|
char hbuff[MAXBUFFERSIZE*2];
|
||||||
char cbuff[MAXBUFFERSIZE];
|
char cbuff[MAXBUFFERSIZE];
|
||||||
@ -238,14 +293,15 @@ void dump_netobj(const struct netobj *nobj)
|
|||||||
else if (nobj->n_len == 0) {
|
else if (nobj->n_len == 0) {
|
||||||
debuglog("Size zero netobj\n");
|
debuglog("Size zero netobj\n");
|
||||||
} else {
|
} else {
|
||||||
dump_static_object(nobj->n_bytes,nobj->n_len,
|
dump_static_object(nobj->n_bytes, nobj->n_len,
|
||||||
hbuff,sizeof(hbuff),cbuff,sizeof(cbuff));
|
hbuff, sizeof(hbuff), cbuff, sizeof(cbuff));
|
||||||
debuglog("netobj: len: %d data: %s ::: %s\n",
|
debuglog("netobj: len: %d data: %s ::: %s\n",
|
||||||
nobj->n_len,hbuff,cbuff);
|
nobj->n_len, hbuff, cbuff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_filelock(const struct file_lock *fl)
|
void
|
||||||
|
dump_filelock(const struct file_lock *fl)
|
||||||
{
|
{
|
||||||
char hbuff[MAXBUFFERSIZE*2];
|
char hbuff[MAXBUFFERSIZE*2];
|
||||||
char cbuff[MAXBUFFERSIZE];
|
char cbuff[MAXBUFFERSIZE];
|
||||||
@ -262,8 +318,8 @@ void dump_filelock(const struct file_lock *fl)
|
|||||||
cbuff, sizeof(cbuff));
|
cbuff, sizeof(cbuff));
|
||||||
debuglog("Filehandle: %8s ::: %8s\n", hbuff, cbuff);
|
debuglog("Filehandle: %8s ::: %8s\n", hbuff, cbuff);
|
||||||
|
|
||||||
debuglog("Dumping nlm4_holder:\n");
|
debuglog("Dumping nlm4_holder:\n"
|
||||||
debuglog("exc: %x svid: %x offset:len %llx:%llx\n",
|
"exc: %x svid: %x offset:len %llx:%llx\n",
|
||||||
fl->client.exclusive, fl->client.svid,
|
fl->client.exclusive, fl->client.svid,
|
||||||
fl->client.l_offset, fl->client.l_len);
|
fl->client.l_offset, fl->client.l_len);
|
||||||
|
|
||||||
@ -284,12 +340,16 @@ void dump_filelock(const struct file_lock *fl)
|
|||||||
struct file_lock *
|
struct file_lock *
|
||||||
malloccopy_filelock(struct file_lock *fl)
|
malloccopy_filelock(struct file_lock *fl)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
copy_nlm4_lock_to_nlm4_holder(const struct nlm4_lock *src,
|
copy_nlm4_lock_to_nlm4_holder(src, exclusive, dest)
|
||||||
const bool_t exclusive, struct nlm4_holder *dest)
|
const struct nlm4_lock *src;
|
||||||
|
const bool_t exclusive;
|
||||||
|
struct nlm4_holder *dest;
|
||||||
{
|
{
|
||||||
|
|
||||||
dest->exclusive = exclusive;
|
dest->exclusive = exclusive;
|
||||||
dest->oh.n_len = src->oh.n_len;
|
dest->oh.n_len = src->oh.n_len;
|
||||||
dest->oh.n_bytes = src->oh.n_bytes;
|
dest->oh.n_bytes = src->oh.n_bytes;
|
||||||
@ -300,14 +360,12 @@ copy_nlm4_lock_to_nlm4_holder(const struct nlm4_lock *src,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* deallocate_file_lock: Free all storage associated with a file lock
|
* deallocate_file_lock: Free all storage associated with a file lock
|
||||||
|
* XXX: Check to see if this gets *all* the dynamic structures.
|
||||||
|
* XXX: It should be placed closer to the file_lock definition.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
deallocate_file_lock(struct file_lock *fl)
|
deallocate_file_lock(struct file_lock *fl)
|
||||||
{
|
{
|
||||||
/* XXX: Check to see if this gets *all* the dynamic structures */
|
|
||||||
/* XXX: It should be placed closer to the file_lock definition */
|
|
||||||
|
|
||||||
free(fl->client.oh.n_bytes);
|
free(fl->client.oh.n_bytes);
|
||||||
free(fl->client_cookie.n_bytes);
|
free(fl->client_cookie.n_bytes);
|
||||||
free(fl);
|
free(fl);
|
||||||
@ -317,13 +375,13 @@ deallocate_file_lock(struct file_lock *fl)
|
|||||||
* regions_overlap(): This function examines the two provided regions for
|
* regions_overlap(): This function examines the two provided regions for
|
||||||
* overlap. It is non-trivial because start+len *CAN* overflow a 64-bit
|
* overlap. It is non-trivial because start+len *CAN* overflow a 64-bit
|
||||||
* unsigned integer and NFS semantics are unspecified on this account.
|
* unsigned integer and NFS semantics are unspecified on this account.
|
||||||
|
* XXX: Check to make sure I got *ALL* the cases.
|
||||||
|
* XXX: This DESPERATELY needs a regression test.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
regions_overlap(const u_int64_t start1, const u_int64_t len1,
|
regions_overlap(start1, len1, start2, len2)
|
||||||
const u_int64_t start2, const u_int64_t len2)
|
const u_int64_t start1, len1, start2, len2;
|
||||||
{
|
{
|
||||||
/* XXX: Check to make sure I got *ALL* the cases */
|
|
||||||
/* XXX: This DESPERATELY needs a regression test */
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
debuglog("Entering region overlap with vals: %llu:%llu--%llu:%llu\n",
|
debuglog("Entering region overlap with vals: %llu:%llu--%llu:%llu\n",
|
||||||
@ -336,29 +394,17 @@ regions_overlap(const u_int64_t start1, const u_int64_t len1,
|
|||||||
/* Regions *must* overlap if they both extend to the end */
|
/* Regions *must* overlap if they both extend to the end */
|
||||||
result = 1;
|
result = 1;
|
||||||
} else if (len1 == 0) {
|
} else if (len1 == 0) {
|
||||||
if (start2+len2 <= start1) {
|
/* Region 2 is completely left of region 1 */
|
||||||
/* Region 2 is completely left of region 1 */
|
result = (start2 + len2 > start1);
|
||||||
result = 0;
|
|
||||||
} else {
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
} else if (len2 == 0) {
|
} else if (len2 == 0) {
|
||||||
if (start1+len1 <= start2) {
|
/* Region 1 is completely left of region 2 */
|
||||||
/* Region 1 is completely left of region 2 */
|
result = (start1 + len1 > start2);
|
||||||
result = 0;
|
|
||||||
} else {
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (start1+len1 <= start2 || start2+len2 <= start1) {
|
/*
|
||||||
/*
|
* 1 is completely left of 2 or
|
||||||
* 1 is completely left of 2 or
|
* 2 is completely left of 1
|
||||||
* 2 is completely left of 1
|
*/
|
||||||
*/
|
result = !(start1+len1 <= start2 || start2+len2 <= start1);
|
||||||
result = 0;
|
|
||||||
} else {
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debuglog("Exiting region overlap with val: %d\n",result);
|
debuglog("Exiting region overlap with val: %d\n",result);
|
||||||
@ -374,30 +420,25 @@ same_netobj(const netobj *n0, const netobj *n1)
|
|||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
retval=0;
|
retval = 0;
|
||||||
|
|
||||||
debuglog("Entering netobj identity check\n");
|
debuglog("Entering netobj identity check\n");
|
||||||
|
|
||||||
if (n0->n_len == n1->n_len) {
|
if (n0->n_len == n1->n_len) {
|
||||||
debuglog("Preliminary length check passed\n");
|
debuglog("Preliminary length check passed\n");
|
||||||
|
retval = !bcmp(n0->n_bytes, n1->n_bytes, n0->n_len);
|
||||||
if (!bcmp(n0->n_bytes,n1->n_bytes,n0->n_len)) {
|
debuglog("netobj %smatch\n", retval ? "" : "mis");
|
||||||
retval = 1;
|
|
||||||
debuglog("netobj match\n");
|
|
||||||
} else {
|
|
||||||
debuglog("netobj mismatch\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* same_filelock_identity: Compares the appropriate bits of a file_lock
|
* same_filelock_identity: Compares the appropriate bits of a file_lock
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
same_filelock_identity(const struct file_lock *fl0,
|
same_filelock_identity(fl0, fl1)
|
||||||
const struct file_lock *fl1)
|
const struct file_lock *fl0, *fl1;
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
@ -405,14 +446,15 @@ same_filelock_identity(const struct file_lock *fl0,
|
|||||||
|
|
||||||
debuglog("Checking filelock identity\n");
|
debuglog("Checking filelock identity\n");
|
||||||
|
|
||||||
if (fl0->client.svid == fl1->client.svid) {
|
/*
|
||||||
/* Process ids match now check host information */
|
* Check process ids and host information.
|
||||||
retval = same_netobj(&(fl0->client.oh),&(fl1->client.oh));
|
*/
|
||||||
}
|
retval = (fl0->client.svid == fl1->client.svid &&
|
||||||
|
same_netobj(&(fl0->client.oh), &(fl1->client.oh)));
|
||||||
|
|
||||||
debuglog("Exiting checking filelock identity: retval: %d\n",retval);
|
debuglog("Exiting checking filelock identity: retval: %d\n",retval);
|
||||||
|
|
||||||
return retval;
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -423,24 +465,18 @@ same_filelock_identity(const struct file_lock *fl0,
|
|||||||
/*
|
/*
|
||||||
* get_lock_matching_unlock: Return a lock which matches the given unlock lock
|
* get_lock_matching_unlock: Return a lock which matches the given unlock lock
|
||||||
* or NULL otehrwise
|
* or NULL otehrwise
|
||||||
|
* XXX: It is a shame that this duplicates so much code from test_nfslock.
|
||||||
*/
|
*/
|
||||||
struct file_lock*
|
struct file_lock *
|
||||||
get_lock_matching_unlock (const struct file_lock *fl)
|
get_lock_matching_unlock(const struct file_lock *fl)
|
||||||
{
|
{
|
||||||
/* XXX: It is annoying that this duplicates so much code from test_nfslock */
|
|
||||||
|
|
||||||
struct file_lock *ifl; /* Iterator */
|
struct file_lock *ifl; /* Iterator */
|
||||||
struct file_lock *retval;
|
|
||||||
|
|
||||||
debuglog("Entering lock_matching_unlock\n");
|
debuglog("Entering lock_matching_unlock\n");
|
||||||
debuglog("********Dump of fl*****************\n");
|
debuglog("********Dump of fl*****************\n");
|
||||||
dump_filelock(fl);
|
dump_filelock(fl);
|
||||||
|
|
||||||
retval = NULL;
|
LIST_FOREACH(ifl, &nfslocklist_head, nfslocklist) {
|
||||||
|
|
||||||
for (ifl = LIST_FIRST(&nfslocklist_head);
|
|
||||||
ifl != NULL && retval == NULL;
|
|
||||||
ifl = LIST_NEXT(ifl, nfslocklist)) {
|
|
||||||
debuglog("Pointer to file lock: %p\n",ifl);
|
debuglog("Pointer to file lock: %p\n",ifl);
|
||||||
|
|
||||||
debuglog("****Dump of ifl****\n");
|
debuglog("****Dump of ifl****\n");
|
||||||
@ -453,32 +489,33 @@ get_lock_matching_unlock (const struct file_lock *fl)
|
|||||||
* security hazard as the filehandle code may bypass normal
|
* security hazard as the filehandle code may bypass normal
|
||||||
* file access controls
|
* file access controls
|
||||||
*/
|
*/
|
||||||
if (!bcmp(&fl->filehandle, &ifl->filehandle,
|
if (bcmp(&fl->filehandle, &ifl->filehandle, sizeof(fhandle_t)))
|
||||||
sizeof(fhandle_t))) {
|
continue;
|
||||||
debuglog("matching_unlock: Filehandles match."
|
|
||||||
" Checking regions\n");
|
|
||||||
|
|
||||||
/* Filehandles match, check for region overlap */
|
debuglog("matching_unlock: Filehandles match, "
|
||||||
if (regions_overlap(fl->client.l_offset, fl->client.l_len,
|
"checking regions\n");
|
||||||
ifl->client.l_offset, ifl->client.l_len)) {
|
|
||||||
debuglog("matching_unlock: Region overlap"
|
|
||||||
" found %llu : %llu -- %llu : %llu\n",
|
|
||||||
fl->client.l_offset,fl->client.l_len,
|
|
||||||
ifl->client.l_offset,ifl->client.l_len);
|
|
||||||
|
|
||||||
/* Regions overlap, check the identity */
|
/* Filehandles match, check for region overlap */
|
||||||
if (same_filelock_identity(fl,ifl)) {
|
if (!regions_overlap(fl->client.l_offset, fl->client.l_len,
|
||||||
debuglog("matching_unlock: Duplicate"
|
ifl->client.l_offset, ifl->client.l_len))
|
||||||
" lock id. Granting\n");
|
continue;
|
||||||
retval = ifl;
|
|
||||||
}
|
debuglog("matching_unlock: Region overlap"
|
||||||
}
|
" found %llu : %llu -- %llu : %llu\n",
|
||||||
}
|
fl->client.l_offset,fl->client.l_len,
|
||||||
|
ifl->client.l_offset,ifl->client.l_len);
|
||||||
|
|
||||||
|
/* Regions overlap, check the identity */
|
||||||
|
if (!same_filelock_identity(fl,ifl))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
debuglog("matching_unlock: Duplicate lock id. Granting\n");
|
||||||
|
return (ifl);
|
||||||
}
|
}
|
||||||
|
|
||||||
debuglog("Exiting lock_matching_unlock\n");
|
debuglog("Exiting lock_matching_unlock\n");
|
||||||
|
|
||||||
return retval;
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -513,9 +550,10 @@ test_nfslock(const struct file_lock *fl, struct file_lock **conflicting_fl)
|
|||||||
dump_filelock(fl);
|
dump_filelock(fl);
|
||||||
debuglog("***********************************\n");
|
debuglog("***********************************\n");
|
||||||
|
|
||||||
for (ifl = LIST_FIRST(&nfslocklist_head);
|
LIST_FOREACH(ifl, &nfslocklist_head, nfslocklist) {
|
||||||
ifl != NULL && retval != NFS_DENIED;
|
if (retval == NFS_DENIED)
|
||||||
ifl = LIST_NEXT(ifl, nfslocklist)) {
|
break;
|
||||||
|
|
||||||
debuglog("Top of lock loop\n");
|
debuglog("Top of lock loop\n");
|
||||||
debuglog("Pointer to file lock: %p\n",ifl);
|
debuglog("Pointer to file lock: %p\n",ifl);
|
||||||
|
|
||||||
@ -531,52 +569,49 @@ test_nfslock(const struct file_lock *fl, struct file_lock **conflicting_fl)
|
|||||||
* security hazard as the filehandle code may bypass normal
|
* security hazard as the filehandle code may bypass normal
|
||||||
* file access controls
|
* file access controls
|
||||||
*/
|
*/
|
||||||
if (!bcmp(&fl->filehandle, &ifl->filehandle,
|
if (bcmp(&fl->filehandle, &ifl->filehandle, sizeof(fhandle_t)))
|
||||||
sizeof(fhandle_t))) {
|
continue;
|
||||||
debuglog("test_nfslock: filehandle match found\n");
|
|
||||||
|
|
||||||
/* Filehandles match, check for region overlap */
|
debuglog("test_nfslock: filehandle match found\n");
|
||||||
if (regions_overlap(fl->client.l_offset, fl->client.l_len,
|
|
||||||
ifl->client.l_offset, ifl->client.l_len)) {
|
|
||||||
debuglog("test_nfslock: Region overlap found"
|
|
||||||
" %llu : %llu -- %llu : %llu\n",
|
|
||||||
fl->client.l_offset,fl->client.l_len,
|
|
||||||
ifl->client.l_offset,ifl->client.l_len);
|
|
||||||
|
|
||||||
/* Regions overlap, check the exclusivity */
|
/* Filehandles match, check for region overlap */
|
||||||
if (fl->client.exclusive ||
|
if (!regions_overlap(fl->client.l_offset, fl->client.l_len,
|
||||||
ifl->client.exclusive) {
|
ifl->client.l_offset, ifl->client.l_len))
|
||||||
debuglog("test_nfslock: "
|
continue;
|
||||||
"Exclusivity failure: %d %d\n",
|
|
||||||
fl->client.exclusive,
|
|
||||||
ifl->client.exclusive);
|
|
||||||
|
|
||||||
if (same_filelock_identity(fl,ifl)) {
|
debuglog("test_nfslock: Region overlap found"
|
||||||
debuglog("test_nfslock: "
|
" %llu : %llu -- %llu : %llu\n",
|
||||||
"Duplicate lock id. "
|
fl->client.l_offset,fl->client.l_len,
|
||||||
"Granting\n");
|
ifl->client.l_offset,ifl->client.l_len);
|
||||||
(*conflicting_fl) = ifl;
|
|
||||||
retval = NFS_GRANTED_DUPLICATE;
|
/* Regions overlap, check the exclusivity */
|
||||||
} else {
|
if (!(fl->client.exclusive || ifl->client.exclusive))
|
||||||
/* locking attempt fails */
|
continue;
|
||||||
debuglog("test_nfslock: "
|
|
||||||
"Lock attempt failed\n");
|
debuglog("test_nfslock: Exclusivity failure: %d %d\n",
|
||||||
debuglog("Desired lock\n");
|
fl->client.exclusive,
|
||||||
dump_filelock(fl);
|
ifl->client.exclusive);
|
||||||
debuglog("Conflicting lock\n");
|
|
||||||
dump_filelock(ifl);
|
if (same_filelock_identity(fl,ifl)) {
|
||||||
(*conflicting_fl) = ifl;
|
debuglog("test_nfslock: Duplicate id. Granting\n");
|
||||||
retval = NFS_DENIED;
|
(*conflicting_fl) = ifl;
|
||||||
}
|
retval = NFS_GRANTED_DUPLICATE;
|
||||||
}
|
} else {
|
||||||
}
|
/* locking attempt fails */
|
||||||
|
debuglog("test_nfslock: Lock attempt failed\n");
|
||||||
|
debuglog("Desired lock\n");
|
||||||
|
dump_filelock(fl);
|
||||||
|
debuglog("Conflicting lock\n");
|
||||||
|
dump_filelock(ifl);
|
||||||
|
(*conflicting_fl) = ifl;
|
||||||
|
retval = NFS_DENIED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debuglog("Dumping file locks\n");
|
debuglog("Dumping file locks\n");
|
||||||
debuglog("Exiting test_nfslock\n");
|
debuglog("Exiting test_nfslock\n");
|
||||||
|
|
||||||
return retval;
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -617,7 +652,7 @@ lock_nfslock(struct file_lock *fl)
|
|||||||
|
|
||||||
debuglog("Exiting lock_nfslock...\n");
|
debuglog("Exiting lock_nfslock...\n");
|
||||||
|
|
||||||
return retval;
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -634,25 +669,25 @@ lock_nfslock(struct file_lock *fl)
|
|||||||
enum nfslock_status
|
enum nfslock_status
|
||||||
delete_nfslock(struct file_lock *fl)
|
delete_nfslock(struct file_lock *fl)
|
||||||
{
|
{
|
||||||
|
|
||||||
LIST_REMOVE(fl, nfslocklist);
|
LIST_REMOVE(fl, nfslocklist);
|
||||||
|
|
||||||
return NFS_GRANTED;
|
return (NFS_GRANTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum split_status {SPL_DISJOINT, SPL_LOCK_CONTAINED, SPL_LOCK_LEFT,
|
|
||||||
SPL_LOCK_RIGHT, SPL_UNLOCK_CONTAINED};
|
|
||||||
|
|
||||||
enum split_status
|
enum split_status
|
||||||
split_nfslock(const struct file_lock *exist_lock,
|
split_nfslock(exist_lock, unlock_lock, right_lock)
|
||||||
const struct file_lock *unlock_lock,
|
const struct file_lock *exist_lock, *unlock_lock, *right_lock;
|
||||||
const struct file_lock *left_lock, const struct file_lock *right_lock)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum nfslock_status
|
enum nfslock_status
|
||||||
unlock_nfslock(const struct file_lock *fl, struct file_lock **released_lock,
|
unlock_nfslock(fl, released_lock, left_lock, right_lock)
|
||||||
struct file_lock *left_lock, struct file_lock *right_lock)
|
const struct file_lock *fl;
|
||||||
|
struct file_lock **released_lock;
|
||||||
|
struct file_lock *left_lock;
|
||||||
|
struct file_lock *right_lock;
|
||||||
{
|
{
|
||||||
struct file_lock *mfl; /* Matching file lock */
|
struct file_lock *mfl; /* Matching file lock */
|
||||||
enum nfslock_status retval;
|
enum nfslock_status retval;
|
||||||
@ -676,28 +711,21 @@ unlock_nfslock(const struct file_lock *fl, struct file_lock **released_lock,
|
|||||||
retval = NFS_GRANTED;
|
retval = NFS_GRANTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* split_status = split_nfslock(mfl,fl,lfl,rfl); */
|
#if 0
|
||||||
|
split_status = split_nfslock(mfl,fl,lfl,rfl);
|
||||||
|
|
||||||
/* if (split_status == SPL_DISJOINT) */
|
if (split_status == SPL_DISJOINT) {
|
||||||
/* { */
|
/* Shouldn't happen, throw error */
|
||||||
/* /* Shouldn't happen, throw error */
|
} else if (split_status == SPL_LOCK_CONTAINED) {
|
||||||
/* } */
|
/* Delete entire lock */
|
||||||
/* else if (split_status == SPL_LOCK_CONTAINED) */
|
} else if (split_status == SPL_LOCK_LEFT) {
|
||||||
/* { */
|
/* Create new lock for left lock and delete old one */
|
||||||
/* /* Delete entire lock */
|
} else if (split_status == SPL_LOCK_RIGHT) {
|
||||||
/* } */
|
/* Create new lock for right lock and delete old one */
|
||||||
/* else if (split_status == SPL_LOCK_LEFT) */
|
} else if (split_status == SPL_UNLOCK_CONTAINED) {
|
||||||
/* { */
|
/* Create new locks for both and then delete old one */
|
||||||
/* /* Create new lock for left lock and delete old one */
|
}
|
||||||
/* } */
|
#endif
|
||||||
/* else if (split_status == SPL_LOCK_RIGHT) */
|
|
||||||
/* { */
|
|
||||||
/* /* Create new lock for right lock and delete old one */
|
|
||||||
/* } */
|
|
||||||
/* else if (split_status == SPL_UNLOCK_CONTAINED) */
|
|
||||||
/* { */
|
|
||||||
/* /* Create new locks for both and then delete old one */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
debuglog("Exiting unlock_nfslock\n");
|
debuglog("Exiting unlock_nfslock\n");
|
||||||
|
|
||||||
@ -712,7 +740,6 @@ enum hwlock_status
|
|||||||
lock_hwlock(struct file_lock *fl)
|
lock_hwlock(struct file_lock *fl)
|
||||||
{
|
{
|
||||||
struct monfile *imf,*nmf;
|
struct monfile *imf,*nmf;
|
||||||
enum hwlock_status retval;
|
|
||||||
int lflags, flerror;
|
int lflags, flerror;
|
||||||
|
|
||||||
/* Scan to see if filehandle already present */
|
/* Scan to see if filehandle already present */
|
||||||
@ -724,95 +751,81 @@ lock_hwlock(struct file_lock *fl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imf == NULL) {
|
/*
|
||||||
/* No filehandle found, create and go */
|
* Filehandle already exists (we control the file)
|
||||||
nmf = malloc(sizeof(struct monfile));
|
* *AND* NFS has already cleared the lock for availability
|
||||||
if (nmf == NULL) {
|
* Grant it and bump the refcount.
|
||||||
debuglog("hwlock resource allocation failure\n");
|
*/
|
||||||
retval = HW_RESERR;
|
if (imf != NULL) {
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX: Is O_RDWR always the correct mode? */
|
|
||||||
nmf->fd = fhopen(&fl->filehandle, O_RDWR);
|
|
||||||
if (nmf->fd < 0) {
|
|
||||||
switch (errno) {
|
|
||||||
case ESTALE:
|
|
||||||
retval = HW_STALEFH;
|
|
||||||
break;
|
|
||||||
case EROFS:
|
|
||||||
retval = HW_READONLY;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
retval = HW_RESERR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
debuglog("fhopen failed (from %16s): %32s\n",
|
|
||||||
fl->client_name, strerror(errno));
|
|
||||||
free(nmf);
|
|
||||||
} else {
|
|
||||||
/* File opened correctly, fill the monitor struct */
|
|
||||||
bcopy(&fl->filehandle, &nmf->filehandle, sizeof(fl->filehandle));
|
|
||||||
nmf->refcount = 1;
|
|
||||||
nmf->exclusive = fl->client.exclusive;
|
|
||||||
|
|
||||||
lflags = (nmf->exclusive == 1) ?
|
|
||||||
(LOCK_EX | LOCK_NB) : (LOCK_SH | LOCK_NB);
|
|
||||||
|
|
||||||
flerror = flock(nmf->fd, lflags);
|
|
||||||
|
|
||||||
if (flerror != 0) {
|
|
||||||
switch (errno) {
|
|
||||||
case EAGAIN:
|
|
||||||
retval = HW_DENIED;
|
|
||||||
break;
|
|
||||||
case ESTALE:
|
|
||||||
retval = HW_STALEFH;
|
|
||||||
break;
|
|
||||||
case EROFS:
|
|
||||||
retval = HW_READONLY;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
retval = HW_RESERR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
debuglog("flock failed (from %16s): %32s\n",
|
|
||||||
fl->client_name, strerror(errno));
|
|
||||||
|
|
||||||
close(nmf->fd);
|
|
||||||
free(nmf);
|
|
||||||
} else {
|
|
||||||
/* File opened and locked */
|
|
||||||
LIST_INSERT_HEAD(&monfilelist_head, nmf, monfilelist);
|
|
||||||
retval = HW_GRANTED;
|
|
||||||
|
|
||||||
debuglog("flock succeeded (from %16s)\n",
|
|
||||||
fl->client_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Filehandle already exists (we control the file)
|
|
||||||
* *AND* NFS has already cleared the lock for availability
|
|
||||||
* Grant it and bump the refcount.
|
|
||||||
*/
|
|
||||||
++(imf->refcount);
|
++(imf->refcount);
|
||||||
retval = HW_GRANTED;
|
return (HW_GRANTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
/* No filehandle found, create and go */
|
||||||
|
nmf = malloc(sizeof(struct monfile));
|
||||||
|
if (nmf == NULL) {
|
||||||
|
debuglog("hwlock resource allocation failure\n");
|
||||||
|
return (HW_RESERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: Is O_RDWR always the correct mode? */
|
||||||
|
nmf->fd = fhopen(&fl->filehandle, O_RDWR);
|
||||||
|
if (nmf->fd < 0) {
|
||||||
|
debuglog("fhopen failed (from %16s): %32s\n",
|
||||||
|
fl->client_name, strerror(errno));
|
||||||
|
free(nmf);
|
||||||
|
switch (errno) {
|
||||||
|
case ESTALE:
|
||||||
|
return (HW_STALEFH);
|
||||||
|
case EROFS:
|
||||||
|
return (HW_READONLY);
|
||||||
|
default:
|
||||||
|
return (HW_RESERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* File opened correctly, fill the monitor struct */
|
||||||
|
bcopy(&fl->filehandle, &nmf->filehandle, sizeof(fl->filehandle));
|
||||||
|
nmf->refcount = 1;
|
||||||
|
nmf->exclusive = fl->client.exclusive;
|
||||||
|
|
||||||
|
lflags = (nmf->exclusive == 1) ?
|
||||||
|
(LOCK_EX | LOCK_NB) : (LOCK_SH | LOCK_NB);
|
||||||
|
|
||||||
|
flerror = flock(nmf->fd, lflags);
|
||||||
|
|
||||||
|
if (flerror != 0) {
|
||||||
|
debuglog("flock failed (from %16s): %32s\n",
|
||||||
|
fl->client_name, strerror(errno));
|
||||||
|
close(nmf->fd);
|
||||||
|
free(nmf);
|
||||||
|
switch (errno) {
|
||||||
|
case EAGAIN:
|
||||||
|
return (HW_DENIED);
|
||||||
|
case ESTALE:
|
||||||
|
return (HW_STALEFH);
|
||||||
|
case EROFS:
|
||||||
|
return (HW_READONLY);
|
||||||
|
default:
|
||||||
|
return (HW_RESERR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* File opened and locked */
|
||||||
|
LIST_INSERT_HEAD(&monfilelist_head, nmf, monfilelist);
|
||||||
|
|
||||||
|
debuglog("flock succeeded (from %16s)\n", fl->client_name);
|
||||||
|
return (HW_GRANTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum hwlock_status
|
enum hwlock_status
|
||||||
unlock_hwlock(const struct file_lock *fl)
|
unlock_hwlock(const struct file_lock *fl)
|
||||||
{
|
{
|
||||||
struct monfile *imf;
|
struct monfile *imf;
|
||||||
enum hwlock_status retval;
|
|
||||||
|
|
||||||
debuglog("Entering unlock_hwlock\n");
|
debuglog("Entering unlock_hwlock\n");
|
||||||
debuglog("Entering loop interation\n");
|
debuglog("Entering loop interation\n");
|
||||||
|
|
||||||
|
|
||||||
/* Scan to see if filehandle already present */
|
/* Scan to see if filehandle already present */
|
||||||
LIST_FOREACH(imf, &monfilelist_head, monfilelist) {
|
LIST_FOREACH(imf, &monfilelist_head, monfilelist) {
|
||||||
@ -827,37 +840,35 @@ unlock_hwlock(const struct file_lock *fl)
|
|||||||
|
|
||||||
if (imf == NULL) {
|
if (imf == NULL) {
|
||||||
/* No lock found */
|
/* No lock found */
|
||||||
debuglog("No hardware lock found.\n");
|
debuglog("Exiting unlock_hwlock (HW_DENIED_NOLOCK)\n");
|
||||||
retval = HW_DENIED_NOLOCK;
|
return (HW_DENIED_NOLOCK);
|
||||||
} else {
|
|
||||||
/* Lock found */
|
|
||||||
--imf->refcount;
|
|
||||||
|
|
||||||
if (imf->refcount < 0) {
|
|
||||||
debuglog("Negative hardware reference count\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imf->refcount <= 0) {
|
|
||||||
close(imf->fd);
|
|
||||||
LIST_REMOVE(imf, monfilelist);
|
|
||||||
free(imf);
|
|
||||||
}
|
|
||||||
retval = HW_GRANTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debuglog("Exiting unlock_hwlock\n");
|
/* Lock found */
|
||||||
|
--imf->refcount;
|
||||||
|
|
||||||
return retval;
|
if (imf->refcount < 0) {
|
||||||
|
debuglog("Negative hardware reference count\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imf->refcount <= 0) {
|
||||||
|
close(imf->fd);
|
||||||
|
LIST_REMOVE(imf, monfilelist);
|
||||||
|
free(imf);
|
||||||
|
}
|
||||||
|
debuglog("Exiting unlock_hwlock (HW_GRANTED)\n");
|
||||||
|
return (HW_GRANTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum hwlock_status
|
enum hwlock_status
|
||||||
test_hwlock(const struct file_lock *fl, struct file_lock **conflicting_fl)
|
test_hwlock(const struct file_lock *fl, struct file_lock **conflicting_fl)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: lock tests on hardware are not required until
|
* XXX: lock tests on hardware are not required until
|
||||||
* true partial file testing is done on the underlying file
|
* true partial file testing is done on the underlying file
|
||||||
*/
|
*/
|
||||||
return HW_RESERR;
|
return (HW_RESERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -871,6 +882,7 @@ test_hwlock(const struct file_lock *fl, struct file_lock **conflicting_fl)
|
|||||||
void
|
void
|
||||||
add_blockingfilelock(struct file_lock *fl)
|
add_blockingfilelock(struct file_lock *fl)
|
||||||
{
|
{
|
||||||
|
|
||||||
debuglog("Entering add_blockingfilelock\n");
|
debuglog("Entering add_blockingfilelock\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -887,6 +899,7 @@ add_blockingfilelock(struct file_lock *fl)
|
|||||||
void
|
void
|
||||||
remove_blockingfilelock(struct file_lock *fl)
|
remove_blockingfilelock(struct file_lock *fl)
|
||||||
{
|
{
|
||||||
|
|
||||||
debuglog("Entering remove_blockingfilelock\n");
|
debuglog("Entering remove_blockingfilelock\n");
|
||||||
|
|
||||||
LIST_REMOVE(fl, nfslocklist);
|
LIST_REMOVE(fl, nfslocklist);
|
||||||
@ -1472,8 +1485,9 @@ do_unlock(struct file_lock *fl)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
do_clear(const char* hostname)
|
do_clear(const char *hostname)
|
||||||
{
|
{
|
||||||
|
|
||||||
clear_partialfilelock(hostname);
|
clear_partialfilelock(hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1663,63 +1677,62 @@ monitor_lock_host(const char *hostname)
|
|||||||
|
|
||||||
rpcret = 0;
|
rpcret = 0;
|
||||||
statflag = 0;
|
statflag = 0;
|
||||||
|
|
||||||
for( ihp=LIST_FIRST(&hostlst_head); ihp != NULL;
|
LIST_FOREACH(ihp, &hostlst_head, hostlst) {
|
||||||
ihp=LIST_NEXT(ihp, hostlst)) {
|
|
||||||
if (strncmp(hostname, ihp->name, SM_MAXSTRLEN) == 0) {
|
if (strncmp(hostname, ihp->name, SM_MAXSTRLEN) == 0) {
|
||||||
/* Host is already monitored, bump refcount */
|
/* Host is already monitored, bump refcount */
|
||||||
++ihp->refcnt;
|
++ihp->refcnt;
|
||||||
/* Host should only be in the monitor list once */
|
/* Host should only be in the monitor list once */
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ihp == NULL) {
|
|
||||||
/* Host is not yet monitored, add it */
|
|
||||||
nhp = malloc(sizeof(struct host));
|
|
||||||
|
|
||||||
if (nhp == NULL) {
|
|
||||||
debuglog("Unable to allocate entry for statd mon\n");
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
/* Allocated new host entry, now fill the fields */
|
|
||||||
strncpy(nhp->name, hostname, SM_MAXSTRLEN);
|
|
||||||
nhp->refcnt = 1;
|
|
||||||
debuglog("Locally Monitoring host %16s\n",hostname);
|
|
||||||
|
|
||||||
debuglog("Attempting to tell statd\n");
|
|
||||||
|
|
||||||
bzero(&smon,sizeof(smon));
|
|
||||||
|
|
||||||
smon.mon_id.mon_name = nhp->name;
|
|
||||||
smon.mon_id.my_id.my_name = "localhost\0";
|
|
||||||
|
|
||||||
smon.mon_id.my_id.my_prog = NLM_PROG;
|
|
||||||
smon.mon_id.my_id.my_vers = NLM_SM;
|
|
||||||
smon.mon_id.my_id.my_proc = NLM_SM_NOTIFY;
|
|
||||||
|
|
||||||
rpcret = callrpc("localhost", SM_PROG, SM_VERS, SM_MON, xdr_mon,
|
|
||||||
&smon, xdr_sm_stat_res, &sres);
|
|
||||||
|
|
||||||
if (rpcret == 0) {
|
|
||||||
if (sres.res_stat == stat_fail) {
|
|
||||||
debuglog("Statd call failed\n");
|
|
||||||
statflag = 0;
|
|
||||||
} else {
|
|
||||||
statflag = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
debuglog("Rpc call to statd failed with return value: %d\n",rpcret);
|
|
||||||
statflag = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statflag == 1) {
|
|
||||||
LIST_INSERT_HEAD(&hostlst_head, nhp, hostlst);
|
|
||||||
} else {
|
|
||||||
free(nhp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Host is not yet monitored, add it */
|
||||||
|
nhp = malloc(sizeof(struct host));
|
||||||
|
|
||||||
|
if (nhp == NULL) {
|
||||||
|
debuglog("Unable to allocate entry for statd mon\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocated new host entry, now fill the fields */
|
||||||
|
strncpy(nhp->name, hostname, SM_MAXSTRLEN);
|
||||||
|
nhp->refcnt = 1;
|
||||||
|
debuglog("Locally Monitoring host %16s\n",hostname);
|
||||||
|
|
||||||
|
debuglog("Attempting to tell statd\n");
|
||||||
|
|
||||||
|
bzero(&smon,sizeof(smon));
|
||||||
|
|
||||||
|
smon.mon_id.mon_name = nhp->name;
|
||||||
|
smon.mon_id.my_id.my_name = "localhost\0";
|
||||||
|
|
||||||
|
smon.mon_id.my_id.my_prog = NLM_PROG;
|
||||||
|
smon.mon_id.my_id.my_vers = NLM_SM;
|
||||||
|
smon.mon_id.my_id.my_proc = NLM_SM_NOTIFY;
|
||||||
|
|
||||||
|
rpcret = callrpc("localhost", SM_PROG, SM_VERS, SM_MON, xdr_mon,
|
||||||
|
&smon, xdr_sm_stat_res, &sres);
|
||||||
|
|
||||||
|
if (rpcret == 0) {
|
||||||
|
if (sres.res_stat == stat_fail) {
|
||||||
|
debuglog("Statd call failed\n");
|
||||||
|
statflag = 0;
|
||||||
|
} else {
|
||||||
|
statflag = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debuglog("Rpc call to statd failed with return value: %d\n",
|
||||||
|
rpcret);
|
||||||
|
statflag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statflag == 1) {
|
||||||
|
LIST_INSERT_HEAD(&hostlst_head, nhp, hostlst);
|
||||||
|
} else {
|
||||||
|
free(nhp);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1747,35 +1760,37 @@ unmonitor_lock_host(const char *hostname)
|
|||||||
|
|
||||||
if (ihp == NULL) {
|
if (ihp == NULL) {
|
||||||
debuglog("Could not find host %16s in mon list\n", hostname);
|
debuglog("Could not find host %16s in mon list\n", hostname);
|
||||||
} else {
|
return;
|
||||||
if (ihp->refcnt <= 0) {
|
|
||||||
if (ihp->refcnt < 0) {
|
|
||||||
debuglog("Negative refcount!: %d\n",
|
|
||||||
ihp->refcnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
debuglog("Attempting to unmonitor host %16s\n",
|
|
||||||
hostname);
|
|
||||||
|
|
||||||
bzero(&smon_id,sizeof(smon_id));
|
|
||||||
|
|
||||||
smon_id.mon_name = (char *)hostname;
|
|
||||||
smon_id.my_id.my_name = "localhost";
|
|
||||||
smon_id.my_id.my_prog = NLM_PROG;
|
|
||||||
smon_id.my_id.my_vers = NLM_SM;
|
|
||||||
smon_id.my_id.my_proc = NLM_SM_NOTIFY;
|
|
||||||
|
|
||||||
rpcret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON, xdr_mon,
|
|
||||||
&smon_id, xdr_sm_stat_res, &smstat);
|
|
||||||
|
|
||||||
if (rpcret != 0) {
|
|
||||||
debuglog("Rpc call to unmonitor statd failed with return value: %d\n",rpcret);
|
|
||||||
}
|
|
||||||
|
|
||||||
LIST_REMOVE(ihp, hostlst);
|
|
||||||
free(ihp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ihp->refcnt > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ihp->refcnt < 0) {
|
||||||
|
debuglog("Negative refcount!: %d\n",
|
||||||
|
ihp->refcnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
debuglog("Attempting to unmonitor host %16s\n", hostname);
|
||||||
|
|
||||||
|
bzero(&smon_id,sizeof(smon_id));
|
||||||
|
|
||||||
|
smon_id.mon_name = (char *)hostname;
|
||||||
|
smon_id.my_id.my_name = "localhost";
|
||||||
|
smon_id.my_id.my_prog = NLM_PROG;
|
||||||
|
smon_id.my_id.my_vers = NLM_SM;
|
||||||
|
smon_id.my_id.my_proc = NLM_SM_NOTIFY;
|
||||||
|
|
||||||
|
rpcret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON, xdr_mon,
|
||||||
|
&smon_id, xdr_sm_stat_res, &smstat);
|
||||||
|
|
||||||
|
if (rpcret != 0) {
|
||||||
|
debuglog("Rpc call to unmonitor statd failed with "
|
||||||
|
" return value: %d\n", rpcret);
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST_REMOVE(ihp, hostlst);
|
||||||
|
free(ihp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user