usually in exclusive lock control of files, programer use busy-wait method with mkdir(),symlink() etc, or use flock(),lockf(),fcntl() etc. and in exclusive lock control of some resources except for files, programer use semaphore. these quality level of exclusive lock control is not constant by programer's skill level. and it is hard to get unified exclusive lock control in whole system, bacause of non-unified program coding in every programs. and even if excellent programer design exclusive lock control, there will be unavoidable difficulty like a deadlock problem.
grmd control exclusive lock with client-server method, you can control exclusive lock of every resources with unified interface. grmd have following features.
$ tar xvzf grmd-0.3.tar.gz $ cd grmd-0.3 $ vi Makefile $ make $ su # make install # vi /usr/local/grmd/keystring # key string for administrator(MAX 256chars) # vi /etc/hosts.allow # vi /etc/hosts.deny(*) SYSVMSG option is needed for kernel configuration of BSD-like system.
# /usr/local/grmd/rc.grmd
$ /usr/local/grmd/rc.grmd -h usage : rc.grmd [-d|--dir home_directory] [-H|--host hostname] [-p|--port port] [-q|--queue queue_count] [-k|--key keystring_file] [-l|--log logfile] [-f|--foreground] -d|--dir home_directory ... home directory. [/usr/local/grmd] -H|--host hostname ... hostname which daemon run in. [localhost] -p|--port port ... socket port which client talk to. [20100] -q|--queue queue_count ... queue count of socket backlog. [128] -k|--key keystring_file ... file (in home_directory) which administrator keystring is written in. [keystring] -l|--log logfile ... file (in home_directory) which daemon record messages to. [logfile] -f|--foreground ... run in foreground [none]
Table.1 | ||
SHARE_LOCK(1) | EXCLUSIVE_LOCK(1) | |
SHARE_LOCK(2) | Get lock | Wait for release |
EXCLUSIVE_LOCK(2) | Wait for release | Wait for release |
GET LOCK +---------------->(Process 1) | | | [Resource 1] [Resource 2] (Process 2) (fig.1)
GET LOCK +---------------->(Process 1) | | | [Resource 1] [Resource 2] | | | (Process 2)<----------------+ GET LOCK (fig.2)
GET LOCK WAIT LOCK +---------------->(Process 1).................+ | : | : | v [Resource 1] [Resource 2] | | | (Process 2)<----------------+ GET LOCK (fig.3)
GET LOCK WAIT LOCK +---------------->(Process 1).................+ | : | : | v [Resource 1] [Resource 2] X | : | : | +.................(Process 2)<----------------+ DEADLOCK!! GET LOCK (fig.4)
lock pid resid lockmode keystring function : lock resource. if resource is already locked by another process, process will wait till resource is released. pid : string which show process id(max 256chars). resid : string which show resource id(max 256chars). lockmode : string which show exclusive lock mode(case insensitive). share_lock, sl, s exclusive_lock, el, x keystring : keystring which should be specified at unlock(max 256chars). return : OK : exclusive lock success DEADLOCK : exclusive lock failure(DEADLOCK) NG : exclusive lock failure
unlock pid resid keystring function : release resource and wakeup next process waiting. pid : string which show process id(max 256chars). resid : string which show resource id(max 256chars). keystring : keystring which is specified at lock(max 256chars). return : OK : release success NG : release failure
spr keystring function : output resource status into logfile(pid-resid). keystring : keystring for administrator(max 256chars). return : OK : success NG : failure
srp keystring function : output resource status into logfile(resid-pid). keystring : keystring for administrator(max 256chars). return : OK : success NG : failure
getpr keystring function : get resource status(pid-resid)ĄŁ keystring : keystring for administrator(max 256chars). return : OK pid resid status keystr : success NG : failure
getrp keystring function : get resource status(resid-pid)ĄŁ keystring : keystring for administrator(max 256chars). return : OK resid pid status keystr : success NG : failure
function : lock resource argment : host, port, pid, resid, lockmode, keystring return : status ex. : $status = grm_lock("localhost", "20100", "process1", "resource1", "SHARE_LOCK", "Gehime"); lockmode : SHARE_LOCK, SL, S EXCLUSIVE_LOCK, EL, X
function : release resource argment : host, port, pid, resid, keystring return : status ex. : $status = grm_unlock("localhost", "20100", "process1", "resource1", "Gehime");
function : output resource status into logfile(pid-resid) argment : host, port, keystring return : status ex. : $status = grm_spr("localhost", "20100", "Gehime");
function : output resource status into logfile(resid-pid) argment : host, port, keystring return : status ex. : $status = grm_srp("localhost", "20100", "Gehime");
function : get resource status(pid-resid) argment : host, port, keystring return : status pid resid status keystr ex. : $responce = grm_getpr("localhost", "20100", "Gehime"); @stat_pid_resid_status_keystr = split(/\n/, $responce); foreach $i (@stat_pid_resid_status_keystr){ ($stat, $pid, $resid, $status, $keystr) = split(/\t/, $i); }
function : get resource status(resid-pid) argment : host, port, keystring return : status resid pid status keystr ex. : $responce = grm_getrp("localhost", "20100", "Gehime"); @stat_resid_pid_status_keystr = split(/\n/, $responce); foreach $i (@stat_resid_pid_status_keystr){ ($stat, $resid, $pid, $status, $keystr) = split(/\t/, $i); }
# sample1.pl lock resource `r1.txt' and `r2.txt', add 1 to data # in resource 100 times as process `p1'. # # sample2.pl lock resource `r2.txt' and `r1.txt', add 1 to data # in resource 100 times as process `p2'. # # sample3.pl lock resource `r1.txt' and `r2.txt', add 1 to data # in resource 100 times as process `p2'. # # pattern which deadlock happen # $ ./sample1 localhost 20100 & ./sample2 localhost 20100 # # pattern which deadlock don't happen # $ ./sample1 localhost 20100 & ./sample3 localhost 20100
$ ./grmd_sweep.pl localhost 20100