[pve-devel] r5471 - in pve-cluster/trunk/data: . perl src
svn-commits at proxmox.com
svn-commits at proxmox.com
Tue Feb 1 12:10:45 CET 2011
Author: dietmar
Date: 2011-02-01 12:10:45 +0100 (Tue, 01 Feb 2011)
New Revision: 5471
Modified:
pve-cluster/trunk/data/ChangeLog
pve-cluster/trunk/data/perl/Cluster.pm
pve-cluster/trunk/data/src/cfs-plug-memdb.c
pve-cluster/trunk/data/src/dcdb.c
pve-cluster/trunk/data/src/memdb.c
pve-cluster/trunk/data/src/memdb.h
Log:
fix lock implementation
Modified: pve-cluster/trunk/data/ChangeLog
===================================================================
--- pve-cluster/trunk/data/ChangeLog 2011-02-01 07:53:24 UTC (rev 5470)
+++ pve-cluster/trunk/data/ChangeLog 2011-02-01 11:10:45 UTC (rev 5471)
@@ -1,3 +1,7 @@
+2011-02-01 Proxmox Support Team <support at proxmox.com>
+
+ * perl/Cluster.pm (cfs_lock_file): first try.
+
2011-01-31 Proxmox Support Team <support at proxmox.com>
* src/dcdb.c (dcdb_deliver): implement a simple distributed lock
Modified: pve-cluster/trunk/data/perl/Cluster.pm
===================================================================
--- pve-cluster/trunk/data/perl/Cluster.pm 2011-02-01 07:53:24 UTC (rev 5470)
+++ pve-cluster/trunk/data/perl/Cluster.pm 2011-02-01 11:10:45 UTC (rev 5471)
@@ -21,7 +21,7 @@
use Data::Dumper; # fixme: remove
-my $lockdir = "/var/lock/pve-manager";
+my $lockdir = "/etc/pve/priv/lock";
mkdir $lockdir;
# x509 certificate utils
@@ -492,17 +492,74 @@
PVE::Tools::file_set_contents($fsname, $raw);
}
+my $cfs_lock = sub {
+ my ($lockid, $timeout, $text, $code, @param) = @_;
+
+ my $res;
+
+ # fixed timeout: cfs locks have a timeout of 120
+ # using 60 gives us another 60 seconds to abort the task
+
+ $timeout = 10 if !$timeout;
+
+ my $filename = "$lockdir/$lockid";
+
+ eval {
+
+ local $SIG{ALRM} = sub { die "can't aquire lock for $text '$lockid': got timeout\n"; };
+
+ alarm ($timeout);
+
+ if (!(mkdir $filename)) {
+ print STDERR "trying to aquire cfs lock '$lockid' ...";
+ while (1) {
+ if (!(mkdir $filename)) {
+ (utime 0, 0, $filename); # cfs unlock request
+ } else {
+ print STDERR " OK\n";
+ last;
+ }
+ sleep(1);
+ }
+ }
+
+ # fixed timeout: cfs locks have a timeout of 120
+ # using 60 gives us another 60 seconds to abort the task
+ alarm(60);
+ local $SIG{ALRM} = sub { die "got lock timeout - aborting command\n"; };
+
+ $res = &$code(@param);
+
+ alarm(0);
+ };
+
+ my $err = $@;
+
+ alarm(0);
+
+ if (!$err || $err !~ /^got lock timeout -/) {
+ rmdir $filename; # cfs unlock
+ }
+
+ if ($err) {
+ $@ = $err;
+ return undef;
+ }
+
+ $@ = undef;
+
+ return $res;
+};
+
sub cfs_lock_file {
my ($filename, $timeout, $text, $code, @param) = @_;
- my $info = $file_info->{$filename} || die "unknown file '$filename'";
+ my $info = $observed->{$filename} || die "unknown file '$filename'";
- my $lockid = $filename;
+ my $lockid = "file-$filename";
$lockid =~ s/[.\/]/_/g;
- # fimxe: do cluster wide lock instead
-
- PVE::Tools::lock_file("$lockdir/.lock-file-$lockid", $timeout, $text, $code, @param);
+ &$cfs_lock($lockid, $timeout, $text, $code, @param);
}
my $log_levels = {
Modified: pve-cluster/trunk/data/src/cfs-plug-memdb.c
===================================================================
--- pve-cluster/trunk/data/src/cfs-plug-memdb.c 2011-02-01 07:53:24 UTC (rev 5470)
+++ pve-cluster/trunk/data/src/cfs-plug-memdb.c 2011-02-01 11:10:45 UTC (rev 5471)
@@ -369,6 +369,7 @@
uint32_t mtime = tv[1].tv_sec;
gboolean unlock_req = FALSE;
+ guchar csum[32];
if (te && mtime == 0 && te->type == DT_DIR &&
path_is_lockdir(path)) {
@@ -376,7 +377,6 @@
}
if (mdb->dfsm) {
- guchar csum[32];
if (unlock_req && memdb_tree_entry_csum(te, csum))
dcdb_send_unlock(mdb->dfsm, path, csum, TRUE);
@@ -384,7 +384,8 @@
NULL, NULL, 0, mtime, 0);
} else {
uint32_t ctime = time(NULL);
- if (unlock_req && memdb_lock_expired(mdb->memdb, path)) {
+ if (unlock_req && memdb_tree_entry_csum(te, csum) &&
+ memdb_lock_expired(mdb->memdb, path, csum)) {
res = memdb_delete(mdb->memdb, path, 0, ctime);
} else {
res = memdb_mtime(mdb->memdb, path, 0, mtime);
Modified: pve-cluster/trunk/data/src/dcdb.c
===================================================================
--- pve-cluster/trunk/data/src/dcdb.c 2011-02-01 07:53:24 UTC (rev 5470)
+++ pve-cluster/trunk/data/src/dcdb.c 2011-02-01 11:10:45 UTC (rev 5471)
@@ -836,7 +836,7 @@
cfs_debug("got valid unlock request message");
- if (memdb_lock_expired(memdb, path)) {
+ if (memdb_lock_expired(memdb, path, csum)) {
cfs_debug("sending unlock message");
dcdb_send_unlock(dfsm, path, csum, FALSE);
}
Modified: pve-cluster/trunk/data/src/memdb.c
===================================================================
--- pve-cluster/trunk/data/src/memdb.c 2011-02-01 07:53:24 UTC (rev 5470)
+++ pve-cluster/trunk/data/src/memdb.c 2011-02-01 11:10:45 UTC (rev 5471)
@@ -339,25 +339,35 @@
return ret;
}
+
gboolean
memdb_lock_expired(
memdb_t *memdb,
- const char *path)
+ const char *path,
+ const guchar csum[32])
{
g_return_val_if_fail(memdb != NULL, FALSE);
g_return_val_if_fail(memdb->locks != NULL, FALSE);
g_return_val_if_fail(path != NULL, FALSE);
+ g_return_val_if_fail(csum != NULL, FALSE);
memdb_lock_info_t *li;
uint32_t ctime = time(NULL);
if ((li = g_hash_table_lookup(memdb->locks, path))) {
+ if (memcmp(csum, li->csum, 32) != 0) {
+ li->ltime = ctime;
+ memcpy(li->csum, csum, 32);
+ g_critical("wrong lock csum - reset timeout");
+ return FALSE;
+ }
if ((ctime > li->ltime) && ((ctime - li->ltime) > CFS_LOCK_TIMEOUT))
return TRUE;
} else {
li = g_new0(memdb_lock_info_t, 1);
li->path = g_strdup(path);
li->ltime = ctime;
+ memcpy(li->csum, csum, 32);
g_hash_table_replace(memdb->locks, li->path, li);
}
@@ -398,13 +408,20 @@
li = g_new0(memdb_lock_info_t, 1);
li->path = g_strdup_printf("priv/lock/%s", lock_te->name);
- memdb_lock_info_t *oldli;
- if ((oldli = g_hash_table_lookup(memdb->locks, lock_te->name))) {
- li->ltime = oldli->ltime;
+ guchar csum[32];
+ if (memdb_tree_entry_csum(lock_te, csum)) {
+ memcpy(li->csum, csum, 32);
+ memdb_lock_info_t *oldli;
+ if ((oldli = g_hash_table_lookup(memdb->locks, lock_te->name)) &&
+ (memcmp(csum, oldli->csum, 32) == 0)) {
+ li->ltime = oldli->ltime;
+ } else {
+ li->ltime = time(NULL);
+ }
+ g_hash_table_insert(memdb->locks, li->path, li);
} else {
- li->ltime = time(NULL);
+ memdb_lock_info_free(li);
}
- g_hash_table_insert(memdb->locks, li->path, li);
}
if (old)
@@ -608,7 +625,10 @@
if (strcmp(dirname, "priv/lock") == 0) {
g_hash_table_remove(memdb->locks, path);
- memdb_lock_expired(memdb, path); // insert a new entry
+ guchar csum[32];
+ if (memdb_tree_entry_csum(te, csum)) {
+ memdb_lock_expired(memdb, path, csum); // insert a new entry
+ }
}
ret = 0;
Modified: pve-cluster/trunk/data/src/memdb.h
===================================================================
--- pve-cluster/trunk/data/src/memdb.h 2011-02-01 07:53:24 UTC (rev 5470)
+++ pve-cluster/trunk/data/src/memdb.h 2011-02-01 11:10:45 UTC (rev 5471)
@@ -71,6 +71,7 @@
typedef struct {
char *path;
guint32 ltime;
+ guchar csum[32];
} memdb_lock_info_t;
typedef struct {
@@ -98,7 +99,8 @@
gboolean
memdb_lock_expired(
memdb_t *memdb,
- const char *path);
+ const char *path,
+ const guchar csum[32]);
void
memdb_update_locks(memdb_t *memdb);
More information about the pve-devel
mailing list