aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/rpc.lockd/lockd_lock.c
diff options
context:
space:
mode:
authorAlfred Perlstein <alfred@FreeBSD.org>2001-11-18 00:41:15 +0000
committerAlfred Perlstein <alfred@FreeBSD.org>2001-11-18 00:41:15 +0000
commit7e589b0b6e414d5618e6bcd0ad8225194c4ec999 (patch)
treeff53d069457f124a6f5f0fcd531258390ac68b02 /usr.sbin/rpc.lockd/lockd_lock.c
parent4945c132445b7569e624c52623e12879028752a8 (diff)
Notes
Diffstat (limited to 'usr.sbin/rpc.lockd/lockd_lock.c')
-rw-r--r--usr.sbin/rpc.lockd/lockd_lock.c1093
1 files changed, 775 insertions, 318 deletions
diff --git a/usr.sbin/rpc.lockd/lockd_lock.c b/usr.sbin/rpc.lockd/lockd_lock.c
index 587336f7c722..6746adc4f0b7 100644
--- a/usr.sbin/rpc.lockd/lockd_lock.c
+++ b/usr.sbin/rpc.lockd/lockd_lock.c
@@ -35,10 +35,10 @@
*
*/
-#define LOCKD_DEBUG
+#define DEBUG 1
#include <stdio.h>
-#ifdef LOCKD_DEBUG
+#ifdef DEBUG
#include <stdarg.h>
#endif
#include <stdlib.h>
@@ -74,8 +74,6 @@
* XXX: All locks are in a linked list, a better structure should be used
* to improve search/access effeciency.
*/
-LIST_HEAD(nfslocklist_head, file_lock);
-struct nfslocklist_head nfslocklist_head = LIST_HEAD_INITIALIZER(nfslocklist_head);
/* struct describing a lock */
struct file_lock {
@@ -88,10 +86,17 @@ struct file_lock {
int nsm_status; /* status from the remote lock manager */
int status; /* lock status, see below */
int flags; /* lock flags, see lockd_lock.h */
+ int blocking; /* blocking lock or not */
pid_t locker; /* pid of the child process trying to get the lock */
int fd; /* file descriptor for this lock */
};
+LIST_HEAD(nfslocklist_head, file_lock);
+struct nfslocklist_head nfslocklist_head = LIST_HEAD_INITIALIZER(nfslocklist_head);
+
+LIST_HEAD(blockedlocklist_head, file_lock);
+struct blockedlocklist_head blockedlocklist_head = LIST_HEAD_INITIALIZER(blockedlocklist_head);
+
/* lock status */
#define LKST_LOCKED 1 /* lock is locked */
/* XXX: Is this flag file specific or lock specific? */
@@ -99,165 +104,190 @@ struct file_lock {
#define LKST_PROCESSING 3 /* child is trying to aquire the lock */
#define LKST_DYING 4 /* must dies when we get news from the child */
-/* list of hosts we monitor */
-LIST_HEAD(hostlst_head, host);
-struct hostlst_head hostlst_head = LIST_HEAD_INITIALIZER(hostlst_head);
-
-/* struct describing a lock */
+/* struct describing a monitored host */
struct host {
LIST_ENTRY(host) hostlst;
char name[SM_MAXSTRLEN];
int refcnt;
};
+/* list of hosts we monitor */
+LIST_HEAD(hostlst_head, host);
+struct hostlst_head hostlst_head = LIST_HEAD_INITIALIZER(hostlst_head);
+
+/*
+ * File monitoring handlers
+ * XXX: These might be able to be removed when kevent support
+ * is placed into the hardware lock/unlock routines. (ie.
+ * let the kernel do all the file monitoring)
+ */
+
+/* Struct describing a monitored file */
+struct monfile {
+ LIST_ENTRY(monfile) monfilelist;
+ fhandle_t filehandle; /* Local access filehandle */
+ int fd; /* file descriptor: remains open until unlock! */
+ int refcount;
+ int exclusive;
+};
+
+/* List of files we monitor */
+LIST_HEAD(monfilelist_head, monfile);
+struct monfilelist_head monfilelist_head = LIST_HEAD_INITIALIZER(monfilelist_head);
static int debugdelay = 0;
-enum nfslock_status { NFS_GRANTED = 0, NFS_GRANTED_DUPLICATE, NFS_DENIED,
- NFS_DENIED_NOLOCK};
+enum nfslock_status { NFS_GRANTED = 0, NFS_GRANTED_DUPLICATE,
+ NFS_DENIED, NFS_DENIED_NOLOCK,
+ NFS_RESERR };
+
+enum hwlock_status { HW_GRANTED = 0, HW_GRANTED_DUPLICATE,
+ HW_DENIED, HW_DENIED_NOLOCK,
+ HW_STALEFH, HW_READONLY, HW_RESERR };
enum partialfilelock_status { PFL_GRANTED=0, PFL_GRANTED_DUPLICATE, PFL_DENIED,
- PFL_NFSDENIED, PFL_NFSDENIED_NOLOCK };
+ PFL_NFSDENIED, PFL_NFSBLOCKED, PFL_NFSDENIED_NOLOCK, PFL_NFSRESERR,
+ PFL_HWDENIED, PFL_HWBLOCKED, PFL_HWDENIED_NOLOCK, PFL_HWRESERR};
+
+enum partialfilelock_status lock_partialfilelock(struct file_lock *fl);
+void send_granted(struct file_lock *fl, int opcode);
void siglock(void);
void sigunlock(void);
void
debuglog(char const *fmt, ...)
{
-#ifdef LOCKD_DEBUG
va_list ap;
- if (debug_level < 1)
+ if (debug_level < 1) {
return;
+ }
sleep(debugdelay);
va_start(ap, fmt);
vsyslog(LOG_DEBUG, fmt, ap);
va_end(ap);
-#endif
}
-void
-dump_static_object(object, s_object, hbuff, s_hbuff, cbuff, s_cbuff)
- const unsigned char* object;
- const int s_object;
- unsigned char* hbuff;
- const int s_hbuff;
- unsigned char* cbuff;
- const int s_cbuff;
+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)
{
- int i, objectsize;
+ int i,objectsize;
- if (debug_level < 2)
+ if (debug_level < 2) {
return;
+ }
- objectsize = s_object;
+ objectsize = sizeof_object;
if (objectsize == 0) {
debuglog("object is size 0\n");
- return;
- }
-
- if (objectsize > MAXOBJECTSIZE) {
- debuglog("Object of size %d being clamped"
- "to size %d\n", objectsize, MAXOBJECTSIZE);
- objectsize = MAXOBJECTSIZE;
- }
-
- if (hbuff != NULL) {
- if (s_hbuff < objectsize*2+1) {
- debuglog("Hbuff not large enough. Increase size\n");
- } else {
- for (i = 0; i < objectsize; i++) {
- sprintf(hbuff + i * 2, "%02x", *(object+i));
- }
- *(hbuff+i*2) = '\0';
+ } else {
+ if (objectsize > MAXOBJECTSIZE) {
+ debuglog("Object of size %d being clamped"
+ "to size %d\n", objectsize, MAXOBJECTSIZE);
+ objectsize = MAXOBJECTSIZE;
}
- }
- if (cbuff != NULL) {
- if (s_cbuff < objectsize+1) {
- debuglog("Cbuff not large enough."
- " Increase Size\n");
+ if (hbuff != NULL) {
+ if (sizeof_hbuff < objectsize*2+1) {
+ debuglog("Hbuff not large enough."
+ " Increase size\n");
+ } else {
+ for(i=0;i<objectsize;i++) {
+ sprintf(hbuff+i*2,"%02x",*(object+i));
+ }
+ *(hbuff+i*2) = '\0';
+ }
}
- for(i=0;i<objectsize;i++) {
- if (*(object+i) >= 32 && *(object+i) <= 127) {
- *(cbuff+i) = *(object+i);
- } else {
- *(cbuff+i) = '.';
+ if (cbuff != NULL) {
+ if (sizeof_cbuff < objectsize+1) {
+ debuglog("Cbuff not large enough."
+ " Increase Size\n");
}
+
+ for(i=0;i<objectsize;i++) {
+ if (*(object+i) >= 32 && *(object+i) <= 127) {
+ *(cbuff+i) = *(object+i);
+ } else {
+ *(cbuff+i) = '.';
+ }
+ }
+ *(cbuff+i) = '\0';
}
- *(cbuff+i) = '\0';
}
}
-void
-dump_netobj(const struct netobj *nobj)
+void dump_netobj(const struct netobj *nobj)
{
char hbuff[MAXBUFFERSIZE*2];
char cbuff[MAXBUFFERSIZE];
- if (debug_level < 2)
+ if (debug_level < 2) {
return;
+ }
if (nobj == NULL) {
debuglog("Null netobj pointer\n");
- } else if (nobj->n_len == 0) {
+ }
+ else if (nobj->n_len == 0) {
debuglog("Size zero netobj\n");
} else {
- dump_static_object(nobj->n_bytes, nobj->n_len,
- hbuff, sizeof(hbuff), cbuff, sizeof(cbuff));
+ dump_static_object(nobj->n_bytes,nobj->n_len,
+ hbuff,sizeof(hbuff),cbuff,sizeof(cbuff));
debuglog("netobj: len: %d data: %s ::: %s\n",
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 cbuff[MAXBUFFERSIZE];
- if (debug_level < 2)
- return;
-
- if (fl == NULL) {
- debuglog("NULL file lock structure\n");
+ if (debug_level < 2) {
return;
}
- debuglog("Dumping file lock structure\n");
+ if (fl != NULL) {
+ debuglog("Dumping file lock structure\n");
- dump_static_object((unsigned char *)&fl->filehandle,
- sizeof(fl->filehandle), hbuff, sizeof(hbuff),
- cbuff, sizeof(cbuff));
- debuglog("Filehandle: %8s ::: %8s\n", hbuff, cbuff);
-
- debuglog("Dumping nlm4_holder:\n");
- debuglog("exc: %x svid: %x offset:len %llx:%llx\n",
- fl->client.exclusive, fl->client.svid,
- fl->client.l_offset, fl->client.l_len);
-
- debuglog("Dumping client identity:\n");
- dump_netobj(&fl->client.oh);
-
- debuglog("Dumping client cookie:\n");
- dump_netobj(&fl->client_cookie);
+ dump_static_object((unsigned char *)&fl->filehandle,
+ sizeof(fl->filehandle), hbuff, sizeof(hbuff),
+ cbuff, sizeof(cbuff));
+ debuglog("Filehandle: %8s ::: %8s\n", hbuff, cbuff);
+
+ debuglog("Dumping nlm4_holder:\n");
+ debuglog("exc: %x svid: %x offset:len %llx:%llx\n",
+ fl->client.exclusive, fl->client.svid,
+ fl->client.l_offset, fl->client.l_len);
+
+ debuglog("Dumping client identity:\n");
+ dump_netobj(&fl->client.oh);
+
+ debuglog("Dumping client cookie:\n");
+ dump_netobj(&fl->client_cookie);
+
+ debuglog("nsm: %d status: %d flags: %d locker: %d"
+ " fd: %d\n", fl->nsm_status, fl->status,
+ fl->flags, fl->locker, fl->fd);
+ } else {
+ debuglog("NULL file lock structure\n");
+ }
+}
- debuglog("nsm: %d status: %d flags: %d locker: %d"
- " fd: %d\n", fl->nsm_status, fl->status,
- fl->flags, fl->locker, fl->fd);
+struct file_lock *
+malloccopy_filelock(struct file_lock *fl)
+{
}
void
-copy_nlm4_lock_to_nlm4_holder(src, exclusive, dest)
- const struct nlm4_lock *src;
- const bool_t exclusive;
- struct nlm4_holder *dest;
+copy_nlm4_lock_to_nlm4_holder(const struct nlm4_lock *src,
+ const bool_t exclusive, struct nlm4_holder *dest)
{
-
dest->exclusive = exclusive;
dest->oh.n_len = src->oh.n_len;
dest->oh.n_bytes = src->oh.n_bytes;
@@ -287,33 +317,51 @@ deallocate_file_lock(struct file_lock *fl)
* unsigned integer and NFS semantics are unspecified on this account.
*/
int
-regions_overlap(start1, len1, start2, len2)
- const u_int64_t start1, len1, start2, len2;
+regions_overlap(const u_int64_t start1, const u_int64_t len1,
+ const u_int64_t start2, const u_int64_t len2)
{
- /* XXX: Check to make sure I got *ALL* the cases */
- /* XXX: This DESPERATELY needs a regression test */
+ /* XXX: Check to make sure I got *ALL* the cases */
+ /* XXX: This DESPERATELY needs a regression test */
+ int result;
+
debuglog("Entering region overlap with vals: %llu:%llu--%llu:%llu\n",
start1, len1, start2, len2);
/* XXX: Look for a way to collapse the region checks */
/* XXX: Need to adjust checks to account for integer overflow */
- if (len1 == 0 && len2 == 0)
- return (1);
-
- if (len1 == 0) {
- /* Region 2 is completely left of region 1 */
- return (!(start2+len2 <= start1));
+ if (len1 == 0 && len2 == 0) {
+ /* Regions *must* overlap if they both extend to the end */
+ result = 1;
+ } else if (len1 == 0) {
+ if (start2+len2 <= start1) {
+ /* Region 2 is completely left of region 1 */
+ result = 0;
+ } else {
+ result = 1;
+ }
} else if (len2 == 0) {
- /* Region 1 is completely left of region 2 */
- return (!(start1+len1 <= start2));
+ if (start1+len1 <= start2) {
+ /* Region 1 is completely left of region 2 */
+ result = 0;
+ } else {
+ result = 1;
+ }
} else {
- /*
- * 1 is completely left of 2 or
- * 2 is completely left of 1
- */
- return (!(start1+len1 <= start2 || start2+len2 <= start1));
+ if (start1+len1 <= start2 || start2+len2 <= start1) {
+ /*
+ * 1 is completely left of 2 or
+ * 2 is completely left of 1
+ */
+ result = 0;
+ } else {
+ result = 1;
+ }
}
+
+ debuglog("Exiting region overlap with val: %d\n",result);
+
+ return (result);
}
/*
@@ -375,17 +423,13 @@ same_filelock_identity(const struct file_lock *fl0,
* or NULL otehrwise
*/
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
- */
+ /* XXX: It is annoying that this duplicates so much code from test_nfslock */
+
struct file_lock *ifl; /* Iterator */
struct file_lock *retval;
- debugdelay = 0;
-
debuglog("Entering lock_matching_unlock\n");
debuglog("********Dump of fl*****************\n");
dump_filelock(fl);
@@ -430,11 +474,9 @@ get_lock_matching_unlock(const struct file_lock *fl)
}
}
- debugdelay = 0;
-
debuglog("Exiting lock_matching_unlock\n");
- return (retval);
+ return retval;
}
/*
@@ -456,20 +498,18 @@ test_nfslock(const struct file_lock *fl, struct file_lock **conflicting_fl)
struct file_lock *ifl; /* Iterator */
enum nfslock_status retval;
+ debuglog("Entering test_nfslock\n");
retval = NFS_GRANTED;
(*conflicting_fl) = NULL;
- if (debug_level > 0) {
- debuglog("Entering test_nfslock\n");
- debuglog("Entering lock search loop\n");
-
- debuglog("***********************************\n");
- debuglog("Dumping match filelock\n");
- debuglog("***********************************\n");
- dump_filelock(fl);
- debuglog("***********************************\n");
- }
+ debuglog("Entering lock search loop\n");
+
+ debuglog("***********************************\n");
+ debuglog("Dumping match filelock\n");
+ debuglog("***********************************\n");
+ dump_filelock(fl);
+ debuglog("***********************************\n");
for (ifl = LIST_FIRST(&nfslocklist_head);
ifl != NULL && retval != NFS_DENIED;
@@ -575,7 +615,7 @@ lock_nfslock(struct file_lock *fl)
debuglog("Exiting lock_nfslock...\n");
- return (retval);
+ return retval;
}
/*
@@ -584,18 +624,17 @@ lock_nfslock(struct file_lock *fl)
* This routine is used to delete a lock out of the NFS lock list
* without regard to status, underlying locks, regions or anything else
*
- * EXERCISE CAUTION USING THIS ROUTINE! It should only be used when
- * you need to flush entries out of the NFS lock list (error conditions,
- * reboot recovery, etc.). It can create huge memory and resource leaks
- * if used improperly.
- *
- * You really wanted unlock_nfslock, instead, didn't you?
+ * Note that this routine *does not deallocate memory* of the lock.
+ * It just disconnects it from the list. The lock can then be used
+ * by other routines without fear of trashing the list.
*/
enum nfslock_status
-delete_nfslock(const struct file_lock *fl)
+delete_nfslock(struct file_lock *fl)
{
- debuglog("delete_nfslock not yet implemented.\n");
+ LIST_REMOVE(fl, nfslocklist);
+
+ return NFS_GRANTED;
}
@@ -610,55 +649,296 @@ split_nfslock(const struct file_lock *exist_lock,
}
enum nfslock_status
-unlock_nfslock(const struct file_lock *fl)
+unlock_nfslock(const struct file_lock *fl, struct file_lock **released_lock,
+ struct file_lock *left_lock, struct file_lock *right_lock)
{
- struct file_lock *lfl,*rfl; /* Left and right locks if split occurs */
struct file_lock *mfl; /* Matching file lock */
enum nfslock_status retval;
- /* Allocate two locks up front or die trying */
-
debuglog("Entering unlock_nfslock\n");
+ *released_lock = NULL;
+ left_lock = NULL;
+ right_lock = NULL;
+
retval = NFS_DENIED_NOLOCK;
- do {
- printf("Attempting to match lock...\n");
- mfl = get_lock_matching_unlock(fl);
+ printf("Attempting to match lock...\n");
+ mfl = get_lock_matching_unlock(fl);
+
+ if (mfl != NULL) {
+ debuglog("Unlock matched\n");
+ /* Unlock the lock since it matches identity */
+ LIST_REMOVE(mfl, nfslocklist);
+ *released_lock = mfl;
+ retval = NFS_GRANTED;
+ }
+
+/* split_status = split_nfslock(mfl,fl,lfl,rfl); */
+
+/* if (split_status == SPL_DISJOINT) */
+/* { */
+/* /* Shouldn't happen, throw error */
+/* } */
+/* else if (split_status == SPL_LOCK_CONTAINED) */
+/* { */
+/* /* Delete entire lock */
+/* } */
+/* else if (split_status == SPL_LOCK_LEFT) */
+/* { */
+/* /* Create new lock for left lock and delete old one */
+/* } */
+/* 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 */
+/* } */
- if (mfl == NULL) {
- /* No matching lock for unlock */
+ debuglog("Exiting unlock_nfslock\n");
+
+ return retval;
+}
+
+/*
+ * Below here are the routines for manipulating the file lock directly
+ * on the disk hardware itself
+ */
+enum hwlock_status
+lock_hwlock(struct file_lock *fl)
+{
+ struct monfile *imf,*nmf;
+ enum hwlock_status retval;
+ int lflags, flerror;
+
+ /* Scan to see if filehandle already present */
+ LIST_FOREACH(imf, &monfilelist_head, monfilelist) {
+ if (bcmp(&fl->filehandle, &imf->filehandle,
+ sizeof(fl->filehandle)) == 0) {
+ /* imf is the correct filehandle */
+ break;
+ }
+ }
+
+ if (imf == NULL) {
+ /* No filehandle found, create and go */
+ nmf = malloc(sizeof(struct monfile));
+ if (nmf == NULL) {
+ debuglog("hwlock resource allocation failure\n");
+ retval = HW_RESERR;
+ 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 {
- debuglog("Unlock matched\n");
- printf("Unlock matched\n");
- /* Unlock the lock if it matches identity */
- LIST_REMOVE(mfl, nfslocklist);
- deallocate_file_lock(mfl);
- retval = NFS_GRANTED;
+ /* 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);
+ }
}
- } while (mfl != NULL);
-
-#if 0
- split_status = split_nfslock(mfl,fl,lfl,rfl);
- switch (split_status) {
- case SPL_DISJOINT:
- /* Shouldn't happen, throw error */
- case SPL_LOCK_CONTAINED:
- /* Delete entire lock */
- case SPL_LOCK_LEFT:
- /* Create new lock for left lock and delete old one */
- case SPL_LOCK_RIGHT:
- /* Create new lock for right lock and delete old one */
- case SPL_UNLOCK_CONTAINED:
- /* Create new locks for both and then delete old one */
+ } 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);
+ retval = HW_GRANTED;
}
-#endif
- debuglog("Exiting unlock_nfslock\n");
+ return retval;
+}
+
+enum hwlock_status
+unlock_hwlock(const struct file_lock *fl)
+{
+ struct monfile *imf;
+ enum hwlock_status retval;
+
+ debuglog("Entering unlock_hwlock\n");
+ debuglog("Entering loop interation\n");
+
+
+ /* Scan to see if filehandle already present */
+ LIST_FOREACH(imf, &monfilelist_head, monfilelist) {
+ if (bcmp(&fl->filehandle, &imf->filehandle,
+ sizeof(fl->filehandle)) == 0) {
+ /* imf is the correct filehandle */
+ break;
+ }
+ }
+
+ debuglog("Completed iteration. Proceeding\n");
+
+ if (imf == NULL) {
+ /* No lock found */
+ debuglog("No hardware lock found.\n");
+ retval = 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");
return retval;
}
+enum hwlock_status
+test_hwlock(const struct file_lock *fl, struct file_lock **conflicting_fl)
+{
+ /*
+ * XXX: lock tests on hardware are not required until
+ * true partial file testing is done on the underlying file
+ */
+ return HW_RESERR;
+}
+
+
+
+/*
+ * Below here are routines for manipulating blocked lock requests
+ * They should only be called from the XXX_partialfilelock routines
+ * if at all possible
+ */
+
+void
+add_blockingfilelock(struct file_lock *fl)
+{
+ debuglog("Entering add_blockingfilelock\n");
+
+ /*
+ * Clear the blocking flag so that it can be reused without
+ * adding it to the blocking queue a second time
+ */
+
+ fl->blocking = 0;
+ LIST_INSERT_HEAD(&blockedlocklist_head, fl, nfslocklist);
+
+ debuglog("Exiting add_blockingfilelock\n");
+}
+
+void
+remove_blockingfilelock(struct file_lock *fl)
+{
+ debuglog("Entering remove_blockingfilelock\n");
+
+ LIST_REMOVE(fl, nfslocklist);
+
+ debuglog("Exiting remove_blockingfilelock\n");
+}
+
+void
+retry_blockingfilelocklist(void)
+{
+ /* Retry all locks in the blocked list */
+ struct file_lock *ifl, *nfl; /* Iterator */
+ enum partialfilelock_status pflstatus;
+
+ debuglog("Entering retry_blockingfilelocklist\n");
+
+ ifl = LIST_FIRST(&blockedlocklist_head);
+ debuglog("Iterator choice %p\n",ifl);
+
+ while (ifl != NULL) {
+ /*
+ * SUBTLE BUG: The next element must be worked out before the
+ * current element has been moved
+ */
+ nfl = LIST_NEXT(ifl, nfslocklist);
+ debuglog("Iterator choice %p\n",ifl);
+ debuglog("Next iterator choice %p\n",nfl);
+
+ /*
+ * SUBTLE BUG: The file_lock must be removed from the
+ * old list so that it's list pointers get disconnected
+ * before being allowed to participate in the new list
+ * which will automatically add it in if necessary.
+ */
+
+ LIST_REMOVE(ifl, nfslocklist);
+ pflstatus = lock_partialfilelock(ifl);
+
+ if (pflstatus == PFL_GRANTED || pflstatus == PFL_GRANTED_DUPLICATE) {
+ debuglog("Granted blocked lock\n");
+ /* lock granted and is now being used */
+ send_granted(ifl,0);
+ } else {
+ /* Reinsert lock back into same place in blocked list */
+ debuglog("Replacing blocked lock\n");
+ LIST_INSERT_BEFORE(nfl, ifl, nfslocklist);
+ }
+
+ /* Valid increment behavior regardless of state of ifl */
+ ifl = nfl;
+ }
+
+ debuglog("Exiting retry_blockingfilelocklist\n");
+}
/*
* Below here are routines associated with manipulating all
@@ -693,6 +973,7 @@ lock_partialfilelock(struct file_lock *fl)
{
enum partialfilelock_status retval;
enum nfslock_status lnlstatus;
+ enum hwlock_status hwstatus;
debuglog("Entering lock_partialfilelock\n");
@@ -705,24 +986,81 @@ lock_partialfilelock(struct file_lock *fl)
lnlstatus = lock_nfslock(fl);
- if (lnlstatus == NFS_GRANTED || lnlstatus == NFS_GRANTED_DUPLICATE) {
- /* XXX: Add the underlying filesystem locking code */
- retval = (lnlstatus == NFS_GRANTED ?
- PFL_GRANTED : PFL_GRANTED_DUPLICATE);
- debuglog("NFS lock granted\n");
-#if 0
- if (do_rawlock(fl) == RL_GRANTED) {
- ;
- } else {
- /* XXX: Unwind the NFS lock which was just granted */
- do_nfsdeletelock(fl);
- retval = PFL_RAWDENIED;
+ switch (lnlstatus) {
+ case NFS_GRANTED:
+ case NFS_GRANTED_DUPLICATE:
+ /*
+ * At this point, the NFS lock is allocated and active.
+ * Remember to clean it up if the hardware lock fails
+ */
+ hwstatus = lock_hwlock(fl);
+
+ switch (hwstatus) {
+ case HW_GRANTED:
+ case HW_GRANTED_DUPLICATE:
+ debuglog("HW GRANTED\n");
+ /*
+ * XXX: Fixme: Check hwstatus for duplicate when
+ * true partial file locking and accounting is
+ * done on the hardware
+ */
+ if (lnlstatus == NFS_GRANTED_DUPLICATE) {
+ retval = PFL_GRANTED_DUPLICATE;
+ } else {
+ retval = PFL_GRANTED;
+ }
+ break;
+ case HW_RESERR:
+ debuglog("HW RESERR\n");
+ retval = PFL_HWRESERR;
+ break;
+ case HW_DENIED:
+ debuglog("HW DENIED\n");
+ retval = PFL_HWDENIED;
+ break;
+ default:
+ debuglog("Unmatched hwstatus %d\n",hwstatus);
+ break;
}
-#endif
- } else {
+
+ if (retval != PFL_GRANTED &&
+ retval != PFL_GRANTED_DUPLICATE) {
+ /* Clean up the NFS lock */
+ debuglog("Deleting trial NFS lock\n");
+ delete_nfslock(fl);
+ }
+ break;
+ case NFS_DENIED:
retval = PFL_NFSDENIED;
- debuglog("NFS lock denied\n");
- dump_filelock(fl);
+ break;
+ case NFS_RESERR:
+ retval = PFL_NFSRESERR;
+ default:
+ debuglog("Unmatched lnlstatus %d\n");
+ retval = PFL_NFSDENIED_NOLOCK;
+ break;
+ }
+
+ /*
+ * By the time fl reaches here, it is completely free again on
+ * failure. The NFS lock done before attempting the
+ * hardware lock has been backed out
+ */
+
+ if (retval == PFL_NFSDENIED || retval == PFL_HWDENIED) {
+ /* Once last chance to check the lock */
+ if (fl->blocking == 1) {
+ /* Queue the lock */
+ debuglog("BLOCKING LOCK RECEIVED\n");
+ retval = (retval == PFL_NFSDENIED ?
+ PFL_NFSBLOCKED : PFL_HWBLOCKED);
+ add_blockingfilelock(fl);
+ dump_filelock(fl);
+ } else {
+ /* Leave retval alone, it's already correct */
+ debuglog("Lock denied. Non-blocking failure\n");
+ dump_filelock(fl);
+ }
}
debuglog("Exiting lock_partialfilelock\n");
@@ -732,30 +1070,90 @@ lock_partialfilelock(struct file_lock *fl)
/*
* unlock_partialfilelock:
- *
*/
enum partialfilelock_status
unlock_partialfilelock(const struct file_lock *fl)
{
+ struct file_lock *lfl,*rfl,*releasedfl,*mfl;
enum partialfilelock_status retval;
- int unlstatus;
+ enum nfslock_status unlstatus;
+ enum hwlock_status unlhwstatus;
debuglog("Entering unlock_partialfilelock\n");
+ releasedfl = NULL;
retval = PFL_DENIED;
- unlstatus = unlock_nfslock(fl);
-
- if (unlstatus == NFS_GRANTED) {
- retval = PFL_GRANTED;
- } else if (unlstatus == NFS_DENIED_NOLOCK) {
- retval = PFL_NFSDENIED_NOLOCK;
- } else {
- retval = PFL_NFSDENIED;
- debuglog("NFS unlock denied\n");
- dump_filelock(fl);
- }
+ /*
+ * Loop is required since multiple little locks
+ * can be allocated and then deallocated with one
+ * big unlock.
+ *
+ * The loop is required to be here so that the nfs &
+ * hw subsystems do not need to communicate with one
+ * one another
+ */
+
+ do {
+ debuglog("Value of releasedfl: %p\n",releasedfl);
+ unlstatus = unlock_nfslock(fl, &releasedfl, lfl, rfl);
+ debuglog("Value of releasedfl: %p\n",releasedfl);
+
+ switch (unlstatus) {
+ case NFS_GRANTED:
+ /* Attempt to unlock on the hardware */
+ debuglog("NFS unlock granted. Attempting hardware unlock\n");
+
+ unlhwstatus = unlock_hwlock(fl);
+ debuglog("HW unlock returned with code %d\n",unlhwstatus);
+
+ switch (unlhwstatus) {
+ case HW_GRANTED:
+ debuglog("HW unlock granted\n");
+ retval = PFL_GRANTED;
+ break;
+ case HW_DENIED_NOLOCK:
+ /* Huh?!?! This shouldn't happen */
+ debuglog("HW unlock denied no lock\n");
+ retval = PFL_HWRESERR;
+ /* Break out of do-while */
+ unlstatus = NFS_RESERR;
+ break;
+ default:
+ debuglog("HW unlock failed\n");
+ retval = PFL_HWRESERR;
+ /* Break out of do-while */
+ unlstatus = NFS_RESERR;
+ break;
+ }
+
+ debuglog("Exiting with status retval: %d\n",retval);
+
+ /*
+ * XXX: this deallocation *still* needs to migrate closer
+ * to the allocation code way up in get_lock or the allocation
+ * code needs to migrate down (violation of "When you write
+ * malloc you must write free")
+ */
+
+ if (releasedfl != NULL) {
+ deallocate_file_lock(releasedfl);
+ }
+
+ retry_blockingfilelocklist();
+ break;
+ case NFS_DENIED_NOLOCK:
+ retval = PFL_GRANTED;
+ debuglog("All locks cleaned out\n");
+ break;
+ default:
+ retval = PFL_NFSRESERR;
+ debuglog("NFS unlock failure\n");
+ dump_filelock(fl);
+ break;
+ }
+ } while (unlstatus == NFS_GRANTED);
debuglog("Exiting unlock_partialfilelock\n");
@@ -806,6 +1204,11 @@ test_partialfilelock(const struct file_lock *fl,
* codes into useful codes to send back to the NFS RPC messaging system
*/
+/*
+ * These routines translate the (relatively) useful return codes back onto
+ * the few return codes which the nlm subsystems wishes to trasmit
+ */
+
enum nlm_stats
do_test(struct file_lock *fl, struct file_lock **conflicting_fl)
{
@@ -816,30 +1219,43 @@ do_test(struct file_lock *fl, struct file_lock **conflicting_fl)
pfsret = test_partialfilelock(fl,conflicting_fl);
- if (pfsret == PFL_GRANTED) {
- debuglog("PFL test lock granted");
+ switch (pfsret) {
+ case PFL_GRANTED:
+ debuglog("PFL test lock granted\n");
dump_filelock(fl);
dump_filelock(*conflicting_fl);
retval = (fl->flags & LOCK_V4) ? nlm4_granted : nlm_granted;
- } else if (pfsret == PFL_GRANTED_DUPLICATE) {
- debuglog("PFL test lock granted--duplicate id detected");
+ break;
+ case PFL_GRANTED_DUPLICATE:
+ debuglog("PFL test lock granted--duplicate id detected\n");
dump_filelock(fl);
dump_filelock(*conflicting_fl);
debuglog("Clearing conflicting_fl for call semantics\n");
*conflicting_fl = NULL;
retval = (fl->flags & LOCK_V4) ? nlm4_granted : nlm_granted;
- } else if (pfsret == PFL_NFSDENIED) {
- debuglog("PFL_NFS test lock denied");
+ break;
+ case PFL_NFSDENIED:
+ case PFL_HWDENIED:
+ debuglog("PFL test lock denied\n");
dump_filelock(fl);
dump_filelock(*conflicting_fl);
retval = (fl->flags & LOCK_V4) ? nlm4_denied : nlm_denied;
- } else {
- debuglog("PFL test lock *FAILED*");
+ break;
+ case PFL_NFSRESERR:
+ case PFL_HWRESERR:
+ debuglog("PFL test lock resource fail\n");
+ dump_filelock(fl);
+ dump_filelock(*conflicting_fl);
+ retval = (fl->flags & LOCK_V4) ? nlm4_denied_nolocks : nlm_denied_nolocks;
+ break;
+ default:
+ debuglog("PFL test lock *FAILED*\n");
dump_filelock(fl);
dump_filelock(*conflicting_fl);
retval = (fl->flags & LOCK_V4) ? nlm4_failed : nlm_denied;
+ break;
}
-
+
debuglog("Exiting do_test...\n");
return retval;
@@ -861,23 +1277,41 @@ do_lock(struct file_lock *fl)
debuglog("Entering do_lock...\n");
pfsret = lock_partialfilelock(fl);
-
- if (pfsret == PFL_GRANTED) {
+
+ switch (pfsret) {
+ case PFL_GRANTED:
debuglog("PFL lock granted");
dump_filelock(fl);
retval = (fl->flags & LOCK_V4) ? nlm4_granted : nlm_granted;
- } else if (pfsret == PFL_GRANTED_DUPLICATE) {
+ break;
+ case PFL_GRANTED_DUPLICATE:
debuglog("PFL lock granted--duplicate id detected");
dump_filelock(fl);
retval = (fl->flags & LOCK_V4) ? nlm4_granted : nlm_granted;
- } else if (pfsret == PFL_NFSDENIED) {
+ break;
+ case PFL_NFSDENIED:
+ case PFL_HWDENIED:
debuglog("PFL_NFS lock denied");
dump_filelock(fl);
retval = (fl->flags & LOCK_V4) ? nlm4_denied : nlm_denied;
- } else {
+ break;
+ case PFL_NFSBLOCKED:
+ case PFL_HWBLOCKED:
+ debuglog("PFL_NFS blocking lock denied. Queued.\n");
+ dump_filelock(fl);
+ retval = (fl->flags & LOCK_V4) ? nlm4_blocked : nlm_blocked;
+ break;
+ case PFL_NFSRESERR:
+ case PFL_HWRESERR:
+ debuglog("PFL lock resource alocation fail\n");
+ dump_filelock(fl);
+ retval = (fl->flags & LOCK_V4) ? nlm4_denied_nolocks : nlm_denied_nolocks;
+ break;
+ default:
debuglog("PFL lock *FAILED*");
dump_filelock(fl);
retval = (fl->flags & LOCK_V4) ? nlm4_failed : nlm_denied;
+ break;
}
debuglog("Exiting do_lock...\n");
@@ -894,26 +1328,36 @@ do_unlock(struct file_lock *fl)
debuglog("Entering do_unlock...\n");
pfsret = unlock_partialfilelock(fl);
- if (pfsret == PFL_GRANTED) {
+ switch (pfsret) {
+ case PFL_GRANTED:
debuglog("PFL unlock granted");
dump_filelock(fl);
retval = (fl->flags & LOCK_V4) ? nlm4_granted : nlm_granted;
- } else if (pfsret == PFL_NFSDENIED) {
+ break;
+ case PFL_NFSDENIED:
+ case PFL_HWDENIED:
debuglog("PFL_NFS unlock denied");
dump_filelock(fl);
retval = (fl->flags & LOCK_V4) ? nlm4_denied : nlm_denied;
- } else if (pfsret == PFL_NFSDENIED_NOLOCK) {
+ break;
+ case PFL_NFSDENIED_NOLOCK:
+ case PFL_HWDENIED_NOLOCK:
debuglog("PFL_NFS no lock found\n");
retval = (fl->flags & LOCK_V4) ? nlm4_granted : nlm_granted;
- } else {
+ break;
+ case PFL_NFSRESERR:
+ case PFL_HWRESERR:
+ debuglog("PFL unlock resource failure");
+ dump_filelock(fl);
+ retval = (fl->flags & LOCK_V4) ? nlm4_denied_nolocks : nlm_denied_nolocks;
+ break;
+ default:
debuglog("PFL unlock *FAILED*");
dump_filelock(fl);
retval = (fl->flags & LOCK_V4) ? nlm4_failed : nlm_denied;
+ break;
}
- /* XXX: Since something has unlocked, recheck the blocked lock queue */
- /* update_blocked_queue(); */
-
debuglog("Exiting do_unlock...\n");
return retval;
@@ -942,9 +1386,7 @@ testlock(struct nlm4_lock *lock, bool_t exclusive, int flags)
copy_nlm4_lock_to_nlm4_holder(lock, exclusive, &test_fl.client);
siglock();
- debugdelay = 0;
do_test(&test_fl, &conflicting_fl);
- debugdelay = 0;
if (conflicting_fl == NULL) {
debuglog("No conflicting lock found\n");
@@ -1024,6 +1466,7 @@ getlock(nlm4_lockargs *lckarg, struct svc_req *rqstp, const int flags)
newfl->nsm_status = lckarg->state;
newfl->status = 0;
newfl->flags = flags;
+ newfl->blocking = lckarg->block;
/*
* newfl is now fully constructed and deallocate_file_lock
@@ -1034,7 +1477,9 @@ getlock(nlm4_lockargs *lckarg, struct svc_req *rqstp, const int flags)
siglock();
debuglog("Pointer to new lock is %p\n",newfl);
+
retval = do_lock(newfl);
+
debuglog("Pointer to new lock is %p\n",newfl);
sigunlock();
@@ -1055,7 +1500,7 @@ getlock(nlm4_lockargs *lckarg, struct svc_req *rqstp, const int flags)
debuglog("Exiting getlock...\n");
- return (retval);
+ return retval;
}
@@ -1067,7 +1512,6 @@ unlock(nlm4_lock *lock, const int flags)
enum nlm_stats err;
siglock();
- debugdelay = 0;
debuglog("Entering unlock...\n");
@@ -1078,7 +1522,6 @@ unlock(nlm4_lock *lock, const int flags)
err = do_unlock(&fl);
- debugdelay = 0;
sigunlock();
debuglog("Exiting unlock...\n");
@@ -1113,8 +1556,9 @@ monitor_lock_host(const char *hostname)
rpcret = 0;
statflag = 0;
-
- LIST_FOREACH(ihp, &hostlst_head, hostlst) {
+
+ for( ihp=LIST_FIRST(&hostlst_head); ihp != NULL;
+ ihp=LIST_NEXT(ihp, hostlst)) {
if (strncmp(hostname, ihp->name, SM_MAXSTRLEN) == 0) {
/* Host is already monitored, bump refcount */
++ihp->refcnt;
@@ -1123,53 +1567,54 @@ monitor_lock_host(const char *hostname)
}
}
- if (ihp != NULL)
- return;
-
- /* 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(struct mon));
-#if 0
- smon.mon_id.mon_name = nhp->name;
- smon.mon_id.my_id.my_name = "localhost";
- 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;
+ 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");
} 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(struct mon));
+
+ /*
+ smon.mon_id.mon_name = nhp->name;
+ smon.mon_id.my_id.my_name = "localhost";
+ 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;
+ }
+ */
+
+ /* XXX: remove this when statd code is fixed */
statflag = 1;
+ if (statflag == 1) {
+ LIST_INSERT_HEAD(&hostlst_head, nhp, hostlst);
+ } else {
+ free(nhp);
+ }
}
- } else {
- debuglog("Rpc call to statd failed with return value: %d\n",
- rpcret);
- statflag = 0;
- }
-#endif 0
-
- /* XXX: remove this when statd code is fixed */
- statflag = 1;
- if (statflag == 1) {
- LIST_INSERT_HEAD(&hostlst_head, nhp, hostlst);
- } else {
- free(nhp);
}
}
@@ -1186,7 +1631,8 @@ unmonitor_lock_host(const char *hostname)
rpcret = 0;
- LIST_FOREACH(ihp, &hostlst_head, hostlst) {
+ for( ihp=LIST_FIRST(&hostlst_head); ihp != NULL;
+ ihp=LIST_NEXT(ihp, hostlst)) {
if (strncmp(hostname, ihp->name, SM_MAXSTRLEN) == 0) {
/* Host is monitored, bump refcount */
--ihp->refcnt;
@@ -1197,31 +1643,38 @@ unmonitor_lock_host(const char *hostname)
if (ihp == NULL) {
debuglog("Could not find host %16s in mon list\n", hostname);
- return;
- }
+ } else {
+ if (ihp->refcnt <= 0) {
+ if (ihp->refcnt < 0) {
+ debuglog("Negative refcount!: %d\n",
+ ihp->refcnt);
+ }
- if (ihp->refcnt < 0)
- debuglog("Negative refcount!: %d\n", ihp->refcnt);
+ debuglog("Attempting to unmonitor host %16s\n",
+ hostname);
- if (ihp->refcnt > 0)
- return;
+ bzero(&smon_id,sizeof(smon_id));
+
+ /*
+ smon_id.mon_name = 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);
+ }
+ */
- debuglog("Attempting to unmonitor host %16s\n", hostname);
- bzero(&smon_id,sizeof(smon_id));
-#if 0
- smon_id.mon_name = 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);
-#endif 0
- LIST_REMOVE(ihp, hostlst);
- free(ihp);
+ LIST_REMOVE(ihp, hostlst);
+ free(ihp);
+ }
+ }
}
/*
@@ -1245,8 +1698,8 @@ notify(const char *hostname, const int state)
debuglog("No action taken in notify!!!\n");
debuglog("****************************\n");
- /* search all lock for this host; if status changed, release the lock */
-#if 0
+ /* search all lock for this host; if status changed, release the lock */
+ /*
siglock();
for (fl = LIST_FIRST(&nfslocklist_head); fl != NULL; fl = next_fl) {
next_fl = LIST_NEXT(fl, nfslocklist);
@@ -1277,13 +1730,12 @@ notify(const char *hostname, const int state)
}
}
sigunlock();
-#endif
+ */
}
/*
* Routines below here have not been modified in the overhaul
*/
-
void
send_granted(fl, opcode)
struct file_lock *fl;
@@ -1296,6 +1748,10 @@ send_granted(fl, opcode)
static struct nlm_res retval;
static struct nlm4_res retval4;
+ debuglog("About to send granted on blocked lock\n");
+ sleep(1);
+ debuglog("Blowing off return send\n");
+
cli = get_client(fl->addr,
(fl->flags & LOCK_V4) ? NLM_VERS4 : NLM_VERS);
if (cli == NULL) {
@@ -1313,7 +1769,6 @@ send_granted(fl, opcode)
if (fl->flags & LOCK_V4) {
static nlm4_testargs res;
-
res.cookie = fl->client_cookie;
res.exclusive = fl->client.exclusive;
res.alock.caller_name = fl->client_name;
@@ -1357,40 +1812,42 @@ send_granted(fl, opcode)
}
}
if (debug_level > 2)
- syslog(LOG_DEBUG, "clnt_call returns %d(%s) for granted",
- success, clnt_sperrno(success));
+ debuglog("clnt_call returns %d(%s) for granted",
+ success, clnt_sperrno(success));
}
/*
- * Are these two routines (siglock/sigunlock) still required since lockd
- * is not spawning off children to service locks anymore?
- * Presumably they were originally put in place to prevent a child's exit
- * from corrupting the lock list so that locks manipulation could be done
- * in the context of the signal handler.
+ * Are these two routines still required since lockd is not spawning off
+ * children to service locks anymore? Presumably they were originally
+ * put in place to prevent a one child from changing the lock list out
+ * from under another one.
*/
+
void
siglock(void)
{
- sigset_t block;
+ sigset_t block;
- sigemptyset(&block);
- sigaddset(&block, SIGCHLD);
+ sigemptyset(&block);
+ sigaddset(&block, SIGCHLD);
- if (sigprocmask(SIG_BLOCK, &block, NULL) == -1) {
- syslog(LOG_WARNING, "siglock failed: %s", strerror(errno));
- }
+ if (sigprocmask(SIG_BLOCK, &block, NULL) < 0) {
+ syslog(LOG_WARNING, "siglock failed: %s", strerror(errno));
+ }
}
void
sigunlock(void)
{
- sigset_t block;
+ sigset_t block;
- sigemptyset(&block);
- sigaddset(&block, SIGCHLD);
-
- if (sigprocmask(SIG_UNBLOCK, &block, NULL) == -1) {
- syslog(LOG_WARNING, "sigunlock failed: %s", strerror(errno));
- }
+ sigemptyset(&block);
+ sigaddset(&block, SIGCHLD);
+
+ if (sigprocmask(SIG_UNBLOCK, &block, NULL) < 0) {
+ syslog(LOG_WARNING, "sigunlock failed: %s", strerror(errno));
+ }
}
+
+