summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Caulfield <pcaulfie@redhat.com>2001-11-20 14:20:49 +0000
committerPatrick Caulfield <pcaulfie@redhat.com>2001-11-20 14:20:49 +0000
commit75ef8629d598259c35b8291b122c7d8f5fb92a92 (patch)
tree97b8847dc6441ba865e11832eca4e53e0a617c0d
parent7a6d29f5d27765d081fdc0210ea1f24beca3f31d (diff)
downloadlvm2-75ef8629d598259c35b8291b122c7d8f5fb92a92.tar.gz
- Add suspend flag to the locking API as we don't always want to suspend the
target LV. - Removed lvm_ prefix from all functions because Joe told me to. - Added super-high-level functions that keep the mainline code clean - comands now just call lock_lvm() and unlock_lvm() [lock/unlock are too glib!] and the library takes care of whether we are clustered or not. It's important that client routines call unlock before finishing not because the API can't clean up afterwards (it does) but because multiple LVM commands can be issued from one lvm invocation and thus they are the same client as far as the CLVMD is concerned. The local locking paths currently don't do anything. Thought: it might be worth renaming this bit of the lib "locking" to make it less obvious that we have clustering code (of sorts) in here. Or maybe that's just job security through obscurity.
-rw-r--r--lib/cmgr/clvm.h5
-rw-r--r--lib/cmgr/cmgr.c110
-rw-r--r--lib/cmgr/cmgr.h15
3 files changed, 100 insertions, 30 deletions
diff --git a/lib/cmgr/clvm.h b/lib/cmgr/clvm.h
index 0028043ab..448b009bc 100644
--- a/lib/cmgr/clvm.h
+++ b/lib/cmgr/clvm.h
@@ -30,8 +30,11 @@ struct clvm_header
#define CLVMD_SOCKNAME "/var/run/clvmd"
/* Command numbers */
-#define CLVMD_CMD_TEST 4
+#define CLVMD_CMD_TEST 4
/* Lock/Unlock commands */
#define CLVMD_CMD_LOCK 30
#define CLVMD_CMD_UNLOCK 31
+
+#define CLVMD_CMD_LOCK_SUSPEND 32
+#define CLVMD_CMD_UNLOCK_RESUME 33
diff --git a/lib/cmgr/cmgr.c b/lib/cmgr/cmgr.c
index c68623e33..81032aa8d 100644
--- a/lib/cmgr/cmgr.c
+++ b/lib/cmgr/cmgr.c
@@ -4,9 +4,9 @@
* This file is released under the LGPL.
*/
-/* Library functions for Cluster Manager
- * These functions are only used when LVM is run in cluster-enabled
- * mode
+/* Locking functions for LVM
+ * The main purpose of this part of the library is to serialise LVM
+ * management operations (across a cluster if necessary)/
*/
@@ -172,7 +172,7 @@ static void build_header(struct clvm_header *head, int cmd, char *node, void *da
}
/* Send a message to a(or all) node(s) in the cluster */
-int lvm_cluster_write(char cmd, char *node, void *data, int len)
+int cluster_write(char cmd, char *node, void *data, int len)
{
char outbuf[sizeof(struct clvm_header)+len+strlen(node)+1];
char *retbuf = NULL;
@@ -197,8 +197,8 @@ int lvm_cluster_write(char cmd, char *node, void *data, int len)
/* API: Send a message to a(or all) node(s) in the cluster
and wait for replies */
-int lvm_cluster_request(char cmd, char *node, void *data, int len,
- lvm_response_t **response, int *num)
+int cluster_request(char cmd, char *node, void *data, int len,
+ lvm_response_t **response, int *num)
{
char outbuf[sizeof(struct clvm_header)+len+strlen(node)+1];
int *outptr;
@@ -286,7 +286,7 @@ int lvm_cluster_request(char cmd, char *node, void *data, int len,
}
/* API: Free reply array */
-int lvm_cluster_free_request(lvm_response_t *response)
+int cluster_free_request(lvm_response_t *response)
{
int *ptr = (int *)response-2;
int i;
@@ -318,13 +318,22 @@ int lvm_cluster_free_request(lvm_response_t *response)
static int num_responses;
static lvm_response_t *response;
-int lvm_lock_for_cluster(char scope, char *name, int verbosity)
+int lock_for_cluster(char scope, char *name, int suspend, int verbosity)
{
int status;
int i;
char *args;
int len;
+ int cmd;
+ /* Validate scope */
+ if (scope != 'V' && scope != 'L' && scope != 'G')
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Allow for NULL in name field */
if (name)
{
len = strlen(name)+2;
@@ -339,9 +348,11 @@ int lvm_lock_for_cluster(char scope, char *name, int verbosity)
}
args[0] = scope;
- status = lvm_cluster_request(CLVMD_CMD_LOCK,
- "", args, len,
- &response, &num_responses);
+ cmd = (suspend)?CLVMD_CMD_LOCK_SUSPEND:CLVMD_CMD_LOCK;
+
+ status = cluster_request(cmd,
+ "", args, len,
+ &response, &num_responses);
/* If any nodes were down then display them and return an error */
for (i=0; i<num_responses; i++)
@@ -358,19 +369,20 @@ int lvm_lock_for_cluster(char scope, char *name, int verbosity)
if (status)
{
int saved_errno = errno;
- lvm_cluster_free_request(response);
+ cluster_free_request(response);
num_responses = 0;
errno = saved_errno;
}
return status;
}
-int lvm_unlock_for_cluster(char scope, char *name, int verbosity)
+int unlock_for_cluster(char scope, char *name, int suspend, int verbosity)
{
int status;
int i;
int len;
int failed;
+ int cmd;
int num_unlock_responses;
char *args;
lvm_response_t *unlock_response;
@@ -379,6 +391,15 @@ int lvm_unlock_for_cluster(char scope, char *name, int verbosity)
if (num_responses == 0)
return 0;
+
+ /* Validate scope */
+ if (scope != 'V' && scope != 'L' && scope != 'G')
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Allow for NULL in name field */
if (name)
{
len = strlen(name)+2;
@@ -393,6 +414,8 @@ int lvm_unlock_for_cluster(char scope, char *name, int verbosity)
}
args[0] = scope;
+ cmd = (suspend)?CLVMD_CMD_UNLOCK_RESUME:CLVMD_CMD_UNLOCK;
+
/* See if it failed anywhere */
failed = 0;
for (i=0; i<num_responses; i++)
@@ -410,10 +433,10 @@ int lvm_unlock_for_cluster(char scope, char *name, int verbosity)
/* Unlock the ones that succeeded */
if (response[i].status == 0)
{
- status = lvm_cluster_request(CLVMD_CMD_UNLOCK,
- response[i].node,
- args, len,
- &unlock_response, &num_unlock_responses);
+ status = cluster_request(cmd,
+ response[i].node,
+ args, len,
+ &unlock_response, &num_unlock_responses);
if (status)
{
if (verbosity)
@@ -426,7 +449,7 @@ int lvm_unlock_for_cluster(char scope, char *name, int verbosity)
fprintf(stderr, "unlock on node %s failed: %s\n",
response[i].node, strerror(unlock_response[0].status));
}
- lvm_cluster_free_request(unlock_response);
+ cluster_free_request(unlock_response);
}
else
{
@@ -439,10 +462,10 @@ int lvm_unlock_for_cluster(char scope, char *name, int verbosity)
else
{
/* All OK, we can do a full cluster unlock */
- status = lvm_cluster_request(CLVMD_CMD_UNLOCK,
- "",
- args, len,
- &unlock_response, &num_unlock_responses);
+ status = cluster_request(cmd,
+ "",
+ args, len,
+ &unlock_response, &num_unlock_responses);
if (status)
{
if (verbosity > 1)
@@ -461,9 +484,48 @@ int lvm_unlock_for_cluster(char scope, char *name, int verbosity)
}
}
}
- lvm_cluster_free_request(unlock_response);
+ cluster_free_request(unlock_response);
}
- lvm_cluster_free_request(response);
+ cluster_free_request(response);
return 0;
}
+
+
+static int clustered = 0;
+
+int lock_lvm(char scope, char *name, int suspend, int verbosity)
+{
+ int status;
+
+ status = lock_for_cluster(scope, name, suspend, verbosity);
+ if (status == -1)
+ {
+ /* ENOENT means clvmd is not running - assume we are not clustered */
+ /* TODO: May need some way of forcing this to fail in the future */
+ if (errno == ENOENT)
+ {
+ clustered = 0;
+ /* TODO: Local Lock/suspend*/
+ return 0;
+ }
+ clustered = 1;
+ return -1;
+ }
+ clustered = 1;
+ return status;
+}
+
+
+int unlock_lvm(char scope, char *name, int suspend, int verbosity)
+{
+ if (!clustered)
+ {
+ /* TODO: Local unlock/resume */
+ return 0;
+ }
+ else
+ {
+ return unlock_for_cluster( scope, name, suspend, verbosity);
+ }
+}
diff --git a/lib/cmgr/cmgr.h b/lib/cmgr/cmgr.h
index 945def14a..0809d008e 100644
--- a/lib/cmgr/cmgr.h
+++ b/lib/cmgr/cmgr.h
@@ -8,12 +8,17 @@ typedef struct lvm_response
} lvm_response_t;
-extern int lvm_cluster_request(char cmd, char *node, void *data, int len,
+extern int cluster_request(char cmd, char *node, void *data, int len,
lvm_response_t **response, int *num);
-extern int lvm_cluster_write(char cmd, char *node, void *data, int len);
-extern int lvm_cluster_free_request(lvm_response_t *response);
+extern int cluster_write(char cmd, char *node, void *data, int len);
+extern int cluster_free_request(lvm_response_t *response);
/* The "high-level" API */
-extern int lvm_lock_for_cluster(char scope, char *name, int verbosity);
-extern int lvm_unlock_for_cluster(char scope, char *name, int verbosity);
+extern int lock_for_cluster(char scope, char *name, int suspend, int verbosity);
+extern int unlock_for_cluster(char scope, char *name, int suspend, int verbosity);
+
+/* The "even higher-level" API that- copes with
+ non-clustered environment. */
+extern int lock_lvm(char scope, char *name, int suspend, int verbosity);
+extern int unlock_lvm(char scope, char *name, int suspend, int verbosity);