Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2
resource-agents
sfex_uuid.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File sfex_uuid.patch of Package resource-agents
Index: resource-agents/tools/sfex.h =================================================================== --- resource-agents.orig/tools/sfex.h 2011-10-31 17:40:17.000000000 +0800 +++ resource-agents/tools/sfex.h 2011-10-31 17:40:55.000000000 +0800 @@ -88,8 +88,8 @@ * (In the Linux kernel 2.6, if this value is not 512 multibles, direct I/O * does not work) - * number of locks --- 4 bytes. This is printable integer number and range - * is from 1 to 999. This must be left-justify, null(0x00) padding, and make + * number of locks --- 8 bytes. This is printable integer number and range + * is from 1 to 9999. This must be left-justify, null(0x00) padding, and make * a last byte null. This is the number of locks following this control data. * * padding --- The size of this member depend on blocksize. It is adjusted so @@ -101,7 +101,7 @@ int version; /* version number */ int revision; /* revision number */ size_t blocksize; /* block size */ - int numlocks; /* number of locks */ + unsigned long numlocks; /* number of locks */ } sfex_controldata; typedef struct sfex_controldata_ondisk { @@ -109,7 +109,7 @@ uint8_t version[4]; uint8_t revision[4]; uint8_t blocksize[8]; - uint8_t numlocks[4]; + uint8_t numlocks[8]; } sfex_controldata_ondisk; /* @@ -145,12 +145,14 @@ char status; /* status of lock */ int count; /* increment counter */ char nodename[256]; /* node name */ + char uuid[36]; } sfex_lockdata; typedef struct sfex_lockdata_ondisk { uint8_t status; uint8_t count[4]; uint8_t nodename[256]; + uint8_t uuid[37]; } sfex_lockdata_ondisk; /* character for lock status. This is used in sfex_lockdata.status */ @@ -160,7 +162,7 @@ /* features of each member of control data and lock data */ #define SFEX_MAGIC "SFEX" #define SFEX_MIN_NUMLOCKS 1 -#define SFEX_MAX_NUMLOCKS 999 +#define SFEX_MAX_NUMLOCKS 9999 #define SFEX_MIN_COUNT 0 #define SFEX_MAX_COUNT 999 #define SFEX_MAX_NODENAME (sizeof(((sfex_lockdata *)0)->nodename) - 1) Index: resource-agents/tools/sfex_daemon.c =================================================================== --- resource-agents.orig/tools/sfex_daemon.c 2011-10-31 17:40:14.000000000 +0800 +++ resource-agents/tools/sfex_daemon.c 2011-11-08 11:58:43.000000000 +0800 @@ -10,6 +10,7 @@ #include <errno.h> #include <sys/types.h> #include <sys/stat.h> +#include <linux/types.h> #include <fcntl.h> #include <syslog.h> #include "sfex.h" @@ -39,28 +40,128 @@ fprintf(dist, "usage: %s [-i <index>] [-c <collision_timeout>] [-t <lock_timeout>] <device>\n", progname); } -static void acquire_lock(void) +static void check_lock(void) { if (read_lockdata(&cdata, &ldata, lock_index) == -1) { cl_log(LOG_ERR, "read_lockdata failed in acquire_lock\n"); exit(EXIT_FAILURE); } + if (ldata.status == SFEX_STATUS_LOCK) { + printf("host=%s, uuid=%s\n", + (const char*)(ldata.nodename), + (const char*)(ldata.uuid)); + } else { + printf("\n"); + } +} + +/* 0 -> false, 1 -> true */ +static inline int is_used_by_uuid(const char* uuid) +{ + if (read_lockdata(&cdata, &ldata, lock_index) == -1) { + cl_log(LOG_ERR, "read_lockdata failed in acquire_lock\n"); + exit(EXIT_FAILURE); + } + return !(strncmp(uuid, ldata.uuid, sizeof(ldata.uuid))); +} - if ((ldata.status == SFEX_STATUS_LOCK) && (strncmp(nodename, (const char*)(ldata.nodename), sizeof(ldata.nodename)))) { +/* 0 -> unlocked, 1 -> locked */ +static inline int is_locked(void) +{ + if (read_lockdata(&cdata, &ldata, lock_index) == -1) { + cl_log(LOG_ERR, "read_lockdata failed in acquire_lock\n"); + exit(EXIT_FAILURE); + } + + if (ldata.status == SFEX_STATUS_LOCK) { unsigned int t = lock_timeout; - while (t > 0) - t = sleep(t); + while (t > 0) t = sleep(t); read_lockdata(&cdata, &ldata_new, lock_index); if (ldata.count != ldata_new.count) { - cl_log(LOG_ERR, "can\'t acquire lock: the lock's already hold by some other node.\n"); + return 1; + } else { + return 0; + } + } + return 0; +} + +#define SFEX_BULK_SIZE 10 + +/* SBDMhash */ +static inline unsigned int uuid2int(const char *str) +{ + unsigned int hash = 0; + + while (*str) + { + if (*str == '-') { str++; continue;} + /* equivalent to: hash = 65599*hash + (*str++); */ + hash = (*str++) + (hash << 6) + (hash << 16) - hash; + } + + return (((hash & 0x7FFFFFFF) % SFEX_MAX_NUMLOCKS)/SFEX_BULK_SIZE)*SFEX_BULK_SIZE; +} + +static inline void search_for_uuid(const char* uuid, unsigned int lock_index_limit) +{ + unsigned int old_lock_index; + old_lock_index = lock_index; + while (lock_index < lock_index_limit) { + if (is_used_by_uuid(uuid)) return; + else lock_index++; + } + lock_index = old_lock_index; +} + +static void acquire_lock(const char* uuid) +{ + + unsigned int lock_index_limit = 0; +/* unsigned int old_lock_index = lock_index; */ + if (uuid) { + if (cdata.numlocks < 9999) { + cl_log(LOG_ERR, "must have at least 9999 lock slots to use uuid based lock.\n"); exit(2); } + lock_index = uuid2int(uuid); + lock_index_limit = lock_index + SFEX_BULK_SIZE; + search_for_uuid(uuid, lock_index_limit); + } else { + lock_index_limit = lock_index + 1; + } + + while (lock_index < lock_index_limit) { + cl_log(LOG_INFO, "Try lock_index = %d\n", lock_index); + if (is_locked()) { + if (strncmp(uuid, (const char*)(ldata.uuid), sizeof(ldata.uuid))) { + cl_log(LOG_INFO, "can\'t acquire lock: the lock is used for other uuid.\n"); + lock_index = lock_index + 1; + continue; + } + if (strncmp(nodename, (const char*)(ldata.nodename), sizeof(ldata.nodename))) { + cl_log(LOG_ERR, "can\'t acquire lock: the lock is already held by other node.\n"); + exit(2); + } else { + cl_log(LOG_ERR, "this lock is already held by me\n"); + exit(2); + } + } else { + break; + } } + if (lock_index == lock_index_limit) { /* we have run out of bulk */ + cl_log(LOG_ERR, "can\'t find free lock slot to hold this uuid.\n"); + exit(2); + } + + /* from now on, we have a unlocked lock slot */ /* The lock acquisition is possible because it was not updated. */ ldata.status = SFEX_STATUS_LOCK; ldata.count = SFEX_NEXT_COUNT(ldata.count); strncpy((char*)(ldata.nodename), nodename, sizeof(ldata.nodename)); + strncpy((char*)(ldata.uuid), uuid, sizeof(ldata.uuid)); if (write_lockdata(&cdata, &ldata, lock_index) == -1) { cl_log(LOG_ERR, "write_lockdata failed\n"); exit(EXIT_FAILURE); @@ -81,7 +182,11 @@ cl_log(LOG_ERR, "read_lockdata failed in collision detection\n"); } if (strncmp((char*)(ldata.nodename), (const char*)(ldata_new.nodename), sizeof(ldata.nodename))) { - cl_log(LOG_ERR, "can\'t acquire lock: collision detected in the air.\n"); + cl_log(LOG_ERR, "can\'t acquire lock: nodename collision detected in the air.\n"); + exit(2); + } + if (strncmp((char*)(ldata.uuid), (const char*)(ldata_new.uuid), sizeof(ldata.uuid))) { + cl_log(LOG_ERR, "can\'t acquire lock: uuid collision detected in the air.\n"); exit(2); } } @@ -190,6 +295,8 @@ { int ret; + int check_status = 0; + char *uuid = NULL; progname = get_progname(argv[0]); nodename = get_nodename(); @@ -201,13 +308,16 @@ /* read command line option */ opterr = 0; while (1) { - int c = getopt(argc, argv, "hi:c:t:m:n:r:"); + int c = getopt(argc, argv, "shi:u:c:t:m:n:r:"); if (c == -1) break; switch (c) { case 'h': /* help*/ usage(stdout); exit(EXIT_SUCCESS); + case 's': /* status */ + check_status = 1; + break; case 'i': /* -i <index> */ { unsigned long l = strtoul(optarg, NULL, 10); @@ -281,6 +391,17 @@ rsc_id = strdup(optarg); } break; + case 'u': + { + uuid = strdup(optarg); + if (strlen(uuid) > 36) { + cl_log(LOG_ERR, "uuid %s is too long. must be less than 36 byte.\n", + uuid); + exit(EXIT_FAILURE); + } + + } + break; case '?': /* error */ usage(stderr); exit(4); @@ -326,8 +447,13 @@ cl_log(LOG_INFO, "Starting SFeX Daemon...\n"); + if (check_status) { + check_lock(); + exit(EXIT_SUCCESS); + } + /* acquire lock first.*/ - acquire_lock(); + acquire_lock(uuid); if (daemon(0, 1) != 0) { cl_perror("%s::%d: daemon() failed.", __FUNCTION__, __LINE__); Index: resource-agents/tools/sfex_lib.c =================================================================== --- resource-agents.orig/tools/sfex_lib.c 2011-10-31 17:40:14.000000000 +0800 +++ resource-agents/tools/sfex_lib.c 2011-11-08 13:05:46.000000000 +0800 @@ -192,7 +192,7 @@ cdata->revision); snprintf ((char *) (block->blocksize), sizeof (block->blocksize), "%u", (unsigned)cdata->blocksize); - snprintf ((char *) (block->numlocks), sizeof (block->numlocks), "%d", + snprintf ((char *) (block->numlocks), sizeof (block->numlocks), "%lu", cdata->numlocks); fd = dev_fd; @@ -252,6 +252,8 @@ ldata->count); snprintf ((char *) (block->nodename), sizeof (block->nodename), "%s", ldata->nodename); + snprintf ((char *) (block->uuid), sizeof (block->uuid), "%s", + ldata->uuid); fd = dev_fd; @@ -419,11 +421,12 @@ ldata->status = block->status; if (ldata->status != SFEX_STATUS_UNLOCK && ldata->status != SFEX_STATUS_LOCK) { - cl_log(LOG_ERR, "lock data format error.\n"); + cl_log(LOG_ERR, "lock data format error:%d.\n",index); return -1; } ldata->count = atoi ((char *) (block->count)); strncpy ((char *) (ldata->nodename), (const char *) (block->nodename), sizeof(block->nodename)); + strncpy ((char *) (ldata->uuid), (const char *) (block->uuid), sizeof(block->uuid)); #ifdef SFEX_DEBUG cl_log(LOG_INFO, "status: %c\n", ldata->status); @@ -458,7 +461,7 @@ #endif if (index > cdata->numlocks) { - cl_log(LOG_ERR, "index %d is too large. %d locks are stored.\n", + cl_log(LOG_ERR, "index %d is too large. %ld locks are stored.\n", index, cdata->numlocks); return -1; } Index: resource-agents/tools/sfex_stat.c =================================================================== --- resource-agents.orig/tools/sfex_stat.c 2011-10-19 23:35:57.000000000 +0800 +++ resource-agents/tools/sfex_stat.c 2011-11-08 13:09:21.000000000 +0800 @@ -78,7 +78,7 @@ printf(" version: %d\n", cdata->version); printf(" revision: %d\n", cdata->revision); printf(" blocksize: %d\n", (int)cdata->blocksize); - printf(" numlocks: %d\n", cdata->numlocks); + printf(" numlocks: %ld\n", cdata->numlocks); } /*
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor