src/host_id.c | 46 +++++++++++++++++++++-------------------------
src/host_id.h | 4 ++--
src/main.c | 8 ++++++--
3 files changed, 29 insertions(+), 29 deletions(-)
New commits:
commit 951d2206702c10381aa74e2ada1fd414b9a710bc
Author: David Teigland <teigland(a)redhat.com>
Date: Mon Apr 11 13:18:12 2011 -0500
sanlock: add lockspace checks
When comparing lockspaces, do a full compare of name, and
host_id path/offset/id when possible. This prevent adding
two lockspaces with the same name but different host_id info.
(Of course two lockspaces with the same never should never
be created in the first place. We can't fully protect
against that, so it's a user error, but we can reject it
when we see it.)
diff --git a/src/host_id.c b/src/host_id.c
index 4f9091a..535307e 100644
--- a/src/host_id.c
+++ b/src/host_id.c
@@ -71,12 +71,17 @@ int print_space_state(struct space *sp, char *str)
return strlen(str);
}
-static struct space *_search_space(char *space_name, struct list_head *head)
+static struct space *_search_space(char *name, struct sync_disk *disk,
+ uint64_t host_id, struct list_head *head)
{
struct space *sp;
list_for_each_entry(sp, head, list) {
- if (strncmp(sp->space_name, space_name, NAME_ID_SIZE))
+ if (strncmp(sp->space_name, name, NAME_ID_SIZE))
+ continue;
+ if (disk && strncmp(sp->host_id_disk.path, disk->path, SANLK_PATH_LEN))
+ continue;
+ if (host_id && sp->host_id != host_id)
continue;
return sp;
}
@@ -107,21 +112,6 @@ int get_space_info(char *space_name, struct space *sp_out)
return rv;
}
-#if 0
-uint64_t get_our_host_id(char *space_name)
-{
- struct space *sp;
- uint64_t id = 0;
-
- pthread_mutex_lock(&spaces_mutex);
- sp = _search_space(space_name, &spaces);
- if (sp)
- id = sp->host_id;
- pthread_mutex_unlock(&spaces_mutex);
- return id;
-}
-#endif
-
int host_id_leader_read(char *space_name, uint64_t host_id,
struct leader_record *leader_ret)
{
@@ -299,12 +289,18 @@ int add_space(struct space *sp)
{
int rv, result;
- if (space_exists(sp->space_name)) {
+ if (space_exists(sp->space_name, &sp->host_id_disk, sp->host_id)) {
log_erros(sp, "add_space exists");
rv = -EEXIST;
goto fail;
}
+ if (space_exists(sp->space_name, NULL, 0)) {
+ log_erros(sp, "add_space name exists with other host info");
+ rv = -EINVAL;
+ goto fail;
+ }
+
rv = open_disks(&sp->host_id_disk, 1);
if (rv != 1) {
log_erros(sp, "add_space open_disk failed %d %s",
@@ -340,8 +336,8 @@ int add_space(struct space *sp)
pthread_mutex_lock(&spaces_mutex);
/* TODO: repeating check here unnecessary if we serialize adds and removes */
- if (_search_space(sp->space_name, &spaces) ||
- _search_space(sp->space_name, &spaces_remove)) {
+ if (_search_space(sp->space_name, NULL, 0, &spaces) ||
+ _search_space(sp->space_name, NULL, 0, &spaces_remove)) {
pthread_mutex_unlock(&spaces_mutex);
log_erros(sp, "add_space duplicate name");
goto fail_stop;
@@ -360,13 +356,13 @@ int add_space(struct space *sp)
return rv;
}
-int rem_space(char *space_name)
+int rem_space(char *name, struct sync_disk *disk, uint64_t host_id)
{
struct space *sp;
int rv = -ENOENT;
pthread_mutex_lock(&spaces_mutex);
- sp = _search_space(space_name, &spaces);
+ sp = _search_space(name, disk, host_id, &spaces);
if (sp) {
sp->external_remove = 1;
rv = 0;
@@ -429,14 +425,14 @@ void clear_spaces(int wait)
pthread_mutex_unlock(&spaces_mutex);
}
-int space_exists(char *space_name)
+int space_exists(char *name, struct sync_disk *disk, uint64_t host_id)
{
struct space *sp;
pthread_mutex_lock(&spaces_mutex);
- sp = _search_space(space_name, &spaces);
+ sp = _search_space(name, disk, host_id, &spaces);
if (!sp)
- sp = _search_space(space_name, &spaces_remove);
+ sp = _search_space(name, disk, host_id, &spaces_remove);
pthread_mutex_unlock(&spaces_mutex);
if (sp)
return 1;
diff --git a/src/host_id.h b/src/host_id.h
index 26c9701..b329b9a 100644
--- a/src/host_id.h
+++ b/src/host_id.h
@@ -15,9 +15,9 @@ int get_space_info(char *space_name, struct space *sp_out);
int host_id_leader_read(char *space_name, uint64_t host_id, struct leader_record
*leader_ret);
int host_id_renewed(struct space *sp);
int add_space(struct space *sp);
-int rem_space(char *space_name);
+int rem_space(char *name, struct sync_disk *disk, uint64_t host_id);
void clear_spaces(int wait);
-int space_exists(char *space_name);
+int space_exists(char *name, struct sync_disk *disk, uint64_t host_id);
void setup_spaces(void);
#endif
diff --git a/src/main.c b/src/main.c
index 0763b86..7dbc573 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1372,13 +1372,17 @@ static void *cmd_rem_lockspace_thread(void *args_in)
with the space_exists name check below when the same lockspace
name was removed and added at once */
- result = rem_space(lockspace.name);
+ result = rem_space(lockspace.name,
+ (struct sync_disk *)&lockspace.host_id_disk,
+ lockspace.host_id);
if (result < 0)
goto reply;
while (1) {
- if (!space_exists(lockspace.name))
+ if (!space_exists(lockspace.name,
+ (struct sync_disk *)&lockspace.host_id_disk,
+ lockspace.host_id))
break;
sleep(1);
}