2 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
5 * This file is part of LVM2.
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
9 * of the GNU General Public License v.2.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 CLVMD Cluster LVM daemon command processor.
20 To add commands to the daemon simply add a processor in do_command and return
21 and messages back in buf and the length in *retlen. The initial value of
22 buflen is the maximum size of the buffer. if buf is not large enough then it
23 may be reallocated by the functions in here to a suitable size bearing in
24 mind that anything larger than the passed-in size will have to be returned
25 using the system LV and so performance will suffer.
27 The status return will be negated and passed back to the originating node.
29 pre- and post- command routines are called only on the local node. The
30 purpose is primarily to get and release locks, though the pre- routine should
31 also do any other local setups required by the command (if any) and can
32 return a failure code that prevents the command from being distributed around
35 The pre- and post- routines are run in their own thread so can block as long
36 they like, do_command is run in the main clvmd thread so should not block for
37 too long. If the pre-command returns an error code (!=0) then the command
38 will not be propogated around the cluster but the post-command WILL be called
40 Also note that the pre and post routine are *always* called on the local
41 node, even if the command to be executed was only requested to run on a
42 remote node. It may peek inside the client structure to check the status of
45 The clients of the daemon must, naturally, understand the return messages and
48 Routines in here may only READ the values in the client structure passed in
49 apart from client->private which they are free to do what they like with.
53 #include "clvmd-common.h"
57 #include "clvmd-comms.h"
60 #include "lvm-functions.h"
64 #include <sys/utsname.h>
67 extern struct cluster_ops *clops;
68 static int restart_clvmd(void);
70 /* This is where all the real work happens:
71 NOTE: client will be NULL when this is executed on a remote node */
72 int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
73 char **buf, int buflen, int *retlen)
75 char *args = msg->node + strlen(msg->node) + 1;
76 int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
80 struct utsname nodeinfo;
81 unsigned char lock_cmd;
82 unsigned char lock_flags;
86 /* Just a test message */
88 if (arglen > buflen) {
90 buflen = arglen + 200;
91 new_buf = realloc(*buf, buflen);
92 if (new_buf == NULL) {
100 *retlen = 1 + dm_snprintf(*buf, buflen,
101 "TEST from %s: %s v%s",
102 nodeinfo.nodename, args,
107 case CLVMD_CMD_LOCK_VG:
109 lock_flags = args[1];
111 /* Check to see if the VG is in use by LVM1 */
112 status = do_check_lvm1(lockname);
113 do_lock_vg(lock_cmd, lock_flags, lockname);
116 case CLVMD_CMD_LOCK_LV:
117 /* This is the biggie */
118 lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
119 lock_flags = args[1];
121 status = do_lock_lv(lock_cmd, lock_flags, lockname);
122 /* Replace EIO with something less scary */
124 *retlen = 1 + dm_snprintf(*buf, buflen, "%s",
125 get_last_lvm_error());
130 case CLVMD_CMD_LOCK_QUERY:
134 if ((locktype = do_lock_query(lockname)))
135 *retlen = 1 + dm_snprintf(*buf, buflen, "%s", locktype);
138 case CLVMD_CMD_REFRESH:
142 case CLVMD_CMD_SET_DEBUG:
146 case CLVMD_CMD_RESTART:
150 case CLVMD_CMD_GET_CLUSTERNAME:
151 status = clops->get_cluster_name(*buf, buflen);
153 *retlen = strlen(*buf)+1;
156 case CLVMD_CMD_VG_BACKUP:
158 * Do not run backup on local node, caller should do that.
161 lvm_do_backup(&args[2]);
165 /* Won't get here because command is validated in pre_command */
169 /* Check the status of the command and return the error text */
171 *retlen = 1 + ((*buf) ? dm_snprintf(*buf, buflen, "%s",
172 strerror(status)) : -1);
179 static int lock_vg(struct local_client *client)
181 struct dm_hash_table *lock_hash;
182 struct clvm_header *header =
183 (struct clvm_header *) client->bits.localsock.cmd;
184 unsigned char lock_cmd;
185 unsigned char lock_flags;
187 char *args = header->node + strlen(header->node) + 1;
192 /* Keep a track of VG locks in our own hash table. In current
193 practice there should only ever be more than two VGs locked
194 if a user tries to merge lots of them at once */
195 if (client->bits.localsock.private) {
196 lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
199 lock_hash = dm_hash_create(3);
202 client->bits.localsock.private = (void *)lock_hash;
205 lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
206 lock_mode = ((int)lock_cmd & LCK_TYPE_MASK);
207 lock_flags = args[1];
209 DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
211 if (lock_mode == LCK_UNLOCK) {
213 lkid = (int)(long)dm_hash_lookup(lock_hash, lockname);
217 status = sync_unlock(lockname, lkid);
221 dm_hash_remove(lock_hash, lockname);
224 /* Read locks need to be PR; other modes get passed through */
225 if (lock_mode == LCK_READ)
226 lock_mode = LCK_PREAD;
227 status = sync_lock(lockname, lock_mode, (lock_cmd & LCK_NONBLOCK) ? LCKF_NOQUEUE : 0, &lkid);
231 dm_hash_insert(lock_hash, lockname, (void *)(long)lkid);
238 /* Pre-command is a good place to get locks that are needed only for the duration
239 of the commands around the cluster (don't forget to free them in post-command),
240 and to sanity check the command arguments */
241 int do_pre_command(struct local_client *client)
243 struct clvm_header *header =
244 (struct clvm_header *) client->bits.localsock.cmd;
245 unsigned char lock_cmd;
246 unsigned char lock_flags;
247 char *args = header->node + strlen(header->node) + 1;
252 switch (header->cmd) {
254 status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
255 client->bits.localsock.private = (void *)(long)lockid;
258 case CLVMD_CMD_LOCK_VG:
260 /* We take out a real lock unless LCK_CACHE was set */
261 if (!strncmp(lockname, "V_", 2) ||
262 !strncmp(lockname, "P_#", 3))
263 status = lock_vg(client);
266 case CLVMD_CMD_LOCK_LV:
268 lock_flags = args[1];
270 status = pre_lock_lv(lock_cmd, lock_flags, lockname);
273 case CLVMD_CMD_REFRESH:
274 case CLVMD_CMD_GET_CLUSTERNAME:
275 case CLVMD_CMD_SET_DEBUG:
276 case CLVMD_CMD_VG_BACKUP:
277 case CLVMD_CMD_LOCK_QUERY:
278 case CLVMD_CMD_RESTART:
282 log_error("Unknown command %d received\n", header->cmd);
288 /* Note that the post-command routine is called even if the pre-command or the real command
290 int do_post_command(struct local_client *client)
292 struct clvm_header *header =
293 (struct clvm_header *) client->bits.localsock.cmd;
295 unsigned char lock_cmd;
296 unsigned char lock_flags;
297 char *args = header->node + strlen(header->node) + 1;
300 switch (header->cmd) {
303 sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
304 client->bits.localsock.private = 0;
307 case CLVMD_CMD_LOCK_VG:
308 case CLVMD_CMD_VG_BACKUP:
309 case CLVMD_CMD_LOCK_QUERY:
310 /* Nothing to do here */
313 case CLVMD_CMD_LOCK_LV:
315 lock_flags = args[1];
317 status = post_lock_lv(lock_cmd, lock_flags, lockname);
324 /* Called when the client is about to be deleted */
325 void cmd_client_cleanup(struct local_client *client)
327 if (client->bits.localsock.private) {
329 struct dm_hash_node *v;
330 struct dm_hash_table *lock_hash =
331 (struct dm_hash_table *)client->bits.localsock.private;
333 dm_hash_iterate(v, lock_hash) {
334 int lkid = (int)(long)dm_hash_get_data(lock_hash, v);
335 char *lockname = dm_hash_get_key(lock_hash, v);
337 DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
338 sync_unlock(lockname, lkid);
341 dm_hash_destroy(lock_hash);
342 client->bits.localsock.private = 0;
347 static int restart_clvmd(void)
350 char *debug_arg = NULL, *lv_name;
351 int i, argc = 0, max_locks = 0;
352 struct dm_hash_node *hn = NULL;
354 DEBUGLOG("clvmd restart requested\n");
356 /* Count exclusively-open LVs */
359 hn = get_next_excl_lock(hn, &lv_name);
362 } while (hn && *lv_name);
364 /* clvmd + locks (-E uuid) + debug (-d X) + NULL */
365 argv = malloc((max_locks * 2 + 4) * sizeof(*argv));
370 * Build the command-line
372 argv[argc++] = strdup("clvmd");
376 /* Propogate debug options */
378 if (!(debug_arg = malloc(16)) ||
379 dm_snprintf(debug_arg, 16, "-d%d", (int)debug) < 0)
381 argv[argc++] = debug_arg;
384 /* Now add the exclusively-open LVs */
386 hn = get_next_excl_lock(hn, &lv_name);
388 argv[argc] = strdup("-E");
391 argv[argc] = strdup(lv_name);
395 DEBUGLOG("excl lock: %s\n", lv_name);
396 hn = get_next_excl_lock(hn, &lv_name);
398 } while (hn && *lv_name);
402 /* NOTE: This will fail when downgrading! */
403 execve(CLVMD_PATH, argv, NULL);
406 DEBUGLOG("Restart of clvmd failed.\n");
408 for (i = 0; i < argc && argv[i]; i++)