[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 04 of 21] blktap3/drivers: Introduce locking functionality
This patch copies files lock.[ch] from blktap2, with minor changes coming from blktap2.5. I haven't looked thoroughly into them, they seem to implement some kind of locking functionality. Signed-off-by: Thanos Makatos <thanos.makatos@xxxxxxxxxx> diff --git a/tools/blktap2/drivers/lock.c b/tools/blktap3/drivers/lock.c copy from tools/blktap2/drivers/lock.c copy to tools/blktap3/drivers/lock.c --- a/tools/blktap2/drivers/lock.c +++ b/tools/blktap3/drivers/lock.c @@ -41,10 +41,9 @@ #include <time.h> #include <dirent.h> #include <limits.h> +#include "blktap3.h" #include "lock.h" -#define unlikely(x) __builtin_expect(!!(x), 0) - /* format: xenlk.hostname.uuid.<xf><rw>*/ #define LF_POSTFIX ".xenlk" #define LFXL_FORMAT LF_POSTFIX ".%s.%s.x%s" @@ -106,7 +105,8 @@ static char *create_lockfn_link(char *fn return lockfn_link; } -static int NFSnormalizedStatTime(char *fn, struct stat *statnow, int *reterrno) +static int NFSnormalizedStatTime(char *fn, struct stat *statnow, + int *reterrno) { int result = LOCK_OK; int uniq; @@ -121,13 +121,20 @@ static int NFSnormalizedStatTime(char *f srandom((int)time(0) ^ pid); uniq = random() % 0xffffff; buf = malloc(strlen(fn) + 24); - if (unlikely(!buf)) { result = LOCK_ENOMEM; goto finish; } + if (unlikely(!buf)) { + result = LOCK_ENOMEM; + goto finish; + } strcpy(buf, fn); sprintf(buf + strlen(buf), ".xen%08d.tmp", uniq); fd = open(buf, O_WRONLY | O_CREAT, 0644); - if (fd == -1) { *reterrno = errno; result = LOCK_EOPEN; goto finish; } + if (fd == -1) { + *reterrno = errno; + result = LOCK_EOPEN; + goto finish; + } clstat = close(fd); if (unlikely(clstat == -1)) { LOG("fail on close\n"); @@ -144,7 +151,7 @@ finish: return result; } -static int writer_eval(char *name, int readonly) +static int writer_eval(char *name, int readonly __attribute__((unused))) { return name[strlen(name)-1] == 'w'; } @@ -173,8 +180,10 @@ static int lock_holder(char *fn, char *l *ioerror = 0; *elt = 0; - if (!dirname) goto finish; - if (!uname) goto finish; + if (!dirname) + goto finish; + if (!uname) + goto finish; /* get directory */ ptr = strrchr(lockfn, '/'); @@ -207,9 +216,12 @@ static int lock_holder(char *fn, char *l char *p1 = strrchr(fn, '/'); char *p2 = strrchr(lockfn, '/'); char *p3 = strrchr(lockfn_link, '/'); - if (p1) p1+=1; - if (p2) p2+=1; - if (p3) p3+=1; + if (p1) + p1 += 1; + if (p2) + p2 += 1; + if (p3) + p3 += 1; if (strcmp(dptr->d_name, p1 ? p1 : fn) && strcmp(dptr->d_name, p2 ? p2 : lockfn) && strcmp(dptr->d_name, p3 ? p3 : lockfn_link) && @@ -250,7 +262,7 @@ static int lock_holder(char *fn, char *l } } dptr = readdir(pd); - if (!dptr && errno) { + if (!dptr && !errno) { *ioerror = EIO; } } @@ -265,7 +277,8 @@ finish: return (*ioerror) ? 1 : status; } -int lock(char *fn_to_lock, char *uuid, int force, int readonly, int *lease_time, int *retstatus) +int lock(char *fn_to_lock, char *uuid, int force, int readonly, + int *lease_time, int *retstatus) { char *lockfn = 0; char *lockfn_xlink = 0; @@ -296,15 +309,27 @@ int lock(char *fn_to_lock, char *uuid, i /* build lock file strings */ lockfn = create_lockfn(fn_to_lock); - if (unlikely(!lockfn)) { status = ENOMEM; *retstatus = LOCK_ENOMEM; goto finish; } + if (unlikely(!lockfn)) { + status = ENOMEM; + *retstatus = LOCK_ENOMEM; + goto finish; + } lockfn_xlink = create_lockfn_link(fn_to_lock, LFXL_FORMAT, uuid, readonly); - if (unlikely(!lockfn_xlink)) { status = ENOMEM; *retstatus = LOCK_ENOMEM; goto finish; } + if (unlikely(!lockfn_xlink)) { + status = ENOMEM; + *retstatus = LOCK_ENOMEM; + goto finish; + } lockfn_flink = create_lockfn_link(fn_to_lock, LFFL_FORMAT, uuid, readonly); - if (unlikely(!lockfn_flink)) { status = ENOMEM; *retstatus = LOCK_ENOMEM; goto finish; } + if (unlikely(!lockfn_flink)) { + status = ENOMEM; + *retstatus = LOCK_ENOMEM; + goto finish; + } try_again: if (retry_attempts++ > RETRY_MAX) { @@ -454,8 +479,7 @@ skip: } tmpstat = unlink(lockfn_xlink); if (unlikely(tmpstat == -1)) { - LOG("error removing linked lock file %s", - lockfn_xlink); + LOG("error removing linked lock file %s", lockfn_xlink); } XSLEEP; status = LOCK_ESTAT; @@ -470,8 +494,7 @@ skip: status = 0; tmpstat = unlink(lockfn_xlink); if (unlikely(tmpstat == -1)) { - LOG("error removing linked lock file %s", - lockfn_xlink); + LOG("error removing linked lock file %s", lockfn_xlink); } goto finish; } else { @@ -483,8 +506,7 @@ skip: } tmpstat = unlink(lockfn_xlink); if (unlikely(tmpstat == -1)) { - LOG("error removing linked lock file %s", - lockfn_xlink); + LOG("error removing linked lock file %s", lockfn_xlink); } XSLEEP; *retstatus = LOCK_EINODE; @@ -554,8 +576,8 @@ finish: } *retstatus = LOCK_EHELD_RD; } - if (established_lease_time) *lease_time = - established_lease_time; + if (established_lease_time) + *lease_time = established_lease_time; } skip_scan: @@ -573,10 +595,12 @@ skip_scan: failed_write = write(fd, lockfn_flink, strlen(lockfn_flink)) != strlen(lockfn_flink); - if (failed_write) status = errno; + if (failed_write) + status = errno; failed_write |= write(fd, tmpbuf, strlen(tmpbuf)) != strlen(tmpbuf); - if (failed_write) status = errno; + if (failed_write) + status = errno; if (failed_write) { clstat = close(fd); if (unlikely(clstat == -1)) { @@ -605,8 +629,7 @@ skip_scan: /* remove exclusive lock, final read/write locks will hold */ tmpstat = unlink(lockfn); if (unlikely(tmpstat == -1)) { - LOG("error removing exclusive lock file %s", - lockfn); + LOG("error removing exclusive lock file %s", lockfn); } free(lockfn); @@ -614,7 +637,8 @@ skip_scan: free(lockfn_flink); /* set lease time to -1 if error, so no one is apt to use it */ - if (*retstatus < 0) *lease_time = -1; + if (*retstatus < 0) + *lease_time = -1; LOG("returning status %d, errno=%d\n", status, errno); return status; @@ -633,7 +657,10 @@ int unlock(char *fn_to_unlock, char *uui lockfn_link = create_lockfn_link(fn_to_unlock, LFFL_FORMAT, uuid, readonly); - if (unlikely(!lockfn_link)) { *status = LOCK_ENOMEM; goto finish; } + if (unlikely(!lockfn_link)) { + *status = LOCK_ENOMEM; + goto finish; + } if (unlink(lockfn_link) == -1) { LOG("error removing linked lock file %s", lockfn_link); @@ -686,7 +713,10 @@ int lock_delta(char *fn, int *ret_lease, ptr += 1; } pd = opendir(dirname); - if (!pd) { reterrno = errno; goto finish; } + if (!pd) { + reterrno = errno; + goto finish; + } dptr = readdir(pd); while (dptr) { @@ -703,8 +733,7 @@ int lock_delta(char *fn, int *ret_lease, strcat(fpath, "/"); strcat(fpath, dptr->d_name); if (lstat(fpath, &statbuf) != -1) { - int diff = (int)statnow.st_mtime - - (int)statbuf.st_mtime; + int diff = (int) statnow.st_mtime - (int) statbuf.st_mtime; /* adjust diff if someone updated the lock between now and when we created the "now" file @@ -744,10 +773,12 @@ finish: free(uname); /* returns smallest lock time, or error */ - if (result == INT_MAX) result = LOCK_ENOLOCK; + if (result == INT_MAX) + result = LOCK_ENOLOCK; /* set lease time to -1 if error, so no one is apt to use it */ - if ((result < 0) || reterrno) *max_lease = -1; + if ((result < 0) || reterrno) + *max_lease = -1; *ret_lease = result; return reterrno; } @@ -769,7 +800,8 @@ static void usage(char *prg) printf(" t : test the file (after random locks)\n"); printf(" r : random lock tests (must ^C)\n"); printf(" u : unlock, readonly? uniqID (default is PID)\n"); - printf(" l : lock, readonly? force?, uniqID (default is PID), lease time\n"); + printf + (" l : lock, readonly? force?, uniqID (default is PID), lease time\n"); } static void test_file(char *fn) @@ -792,6 +824,7 @@ static void test_file(char *fn) } prev_count = count + 1; } + fclose(fptr); } static void random_locks(char *fn) @@ -841,10 +874,10 @@ static void random_locks(char *fn) int bw = bytes-2; while (bw && filebuf[bw]!='\n') bw--; - if (!bw) bw = -1; + if (!bw) + bw = -1; sscanf(&filebuf[bw+1], - "%d %d %d", - &count, &dummy, &dummy); + "%d %d %d", &count, &dummy, &dummy); count += 1; } lseek(fd, 0, SEEK_END); @@ -919,15 +952,27 @@ int main(int argc, char *argv[]) } else if (!strcmp(argv[1],"p")) { perf_lock(argv[2], argc < 3 ? 100000 : atoi(argv[3])); } else if (!strcmp(argv[1],"l")) { - if (argc < 4) force = 0; else force = atoi(argv[3]); - if (argc < 5) readonly = 0; else readonly = atoi(argv[4]); - if (argc >= 6) ptr = argv[5]; - if (argc == 7) lease = atoi(argv[6]); + if (argc < 4) + force = 0; + else + force = atoi(argv[3]); + if (argc < 5) + readonly = 0; + else + readonly = atoi(argv[4]); + if (argc >= 6) + ptr = argv[5]; + if (argc == 7) + lease = atoi(argv[6]); status = lock(argv[2], ptr, readonly, force, &lease, &intstatus); printf("lock status = %d\n", status); } else if (!strcmp(argv[1],"u") ) { - if (argc < 5) readonly = 0; else readonly = atoi(argv[3]); - if (argc == 5) ptr = argv[4]; + if (argc < 5) + readonly = 0; + else + readonly = atoi(argv[3]); + if (argc == 5) + ptr = argv[4]; status = unlock(argv[2], ptr, readonly, &intstatus); printf("unlock status = %d\n", intstatus); } else { @@ -949,17 +994,19 @@ static void usage(char *prg) " unlock <filename> <r|w> <uniqid>\n" " lock <filename> <r|w> <0|1> <uniqid> <leasetime>\n", prg); printf(" delta : get time since lock last refreshed\n"); - printf(" returns delta time and max lease time in seconds\n"); + printf + (" returns delta time and max lease time in seconds\n"); printf(" unlock: unlock request filename, r|w, uniqID\n"); printf(" returns status (success is 0)\n"); - printf(" lock : lock request filename, r|w, force?, uniqID, lease time request\n"); - printf(" returns status (success is 0) and established lease time in seconds\n"); + printf + (" lock : lock request filename, r|w, force?, uniqID, lease time request\n"); + printf + (" returns status (success is 0) and established lease time in seconds\n"); } int main(int argc, char *argv[]) { int status = 0; - int dlock; char *ptr; int force; int readonly; diff --git a/tools/blktap2/drivers/lock.h b/tools/blktap3/drivers/lock.h copy from tools/blktap2/drivers/lock.h copy to tools/blktap3/drivers/lock.h _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |