4 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
9 * This copyrighted material is made available to anyone wishing to use,
10 * modify, copy, or redistribute it subject to the terms and conditions
11 * of the GNU General Public License v.2.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 CLVMD Cluster LVM daemon command processor.
22 To add commands to the daemon simply add a processor in do_command and return
23 and messages back in buf and the length in *retlen. The initial value of
24 buflen is the maximum size of the buffer. if buf is not large enough then it
25 may be reallocated by the functions in here to a suitable size bearing in
26 mind that anything larger than the passed-in size will have to be returned
27 using the system LV and so performance will suffer.
29 The status return will be negated and passed back to the originating node.
31 pre- and post- command routines are called only on the local node. The
32 purpose is primarily to get and release locks, though the pre- routine should
33 also do any other local setups required by the command (if any) and can
34 return a failure code that prevents the command from being distributed around
37 The pre- and post- routines are run in their own thread so can block as long
38 they like, do_command is run in the main clvmd thread so should not block for
39 too long. If the pre-command returns an error code (!=0) then the command
40 will not be propogated around the cluster but the post-command WILL be called
42 Also note that the pre and post routine are *always* called on the local
43 node, even if the command to be executed was only requested to run on a
44 remote node. It may peek inside the client structure to check the status of
47 The clients of the daemon must, naturally, understand the return messages and
50 Routines in here may only READ the values in the client structure passed in
51 apart from client->private which they are free to do what they like with.
56 #define _FILE_OFFSET_BITS 64
58 #include <configure.h>
60 #include <sys/types.h>
61 #include <sys/utsname.h>
62 #include <sys/ioctl.h>
63 #include <sys/socket.h>
73 #include <libdevmapper.h>
77 #include "lvm-logging.h"
78 #include "lvm-functions.h"
79 #include "clvmd-comms.h"
84 extern struct cluster_ops
*clops
;
86 /* This is where all the real work happens:
87 NOTE: client will be NULL when this is executed on a remote node */
88 int do_command(struct local_client
*client
, struct clvm_header
*msg
, int msglen
,
89 char **buf
, int buflen
, int *retlen
)
91 char *args
= msg
->node
+ strlen(msg
->node
) + 1;
92 int arglen
= msglen
- sizeof(struct clvm_header
) - strlen(msg
->node
);
96 struct utsname nodeinfo
;
97 unsigned char lock_cmd
;
98 unsigned char lock_flags
;
102 /* Just a test message */
104 if (arglen
> buflen
) {
106 buflen
= arglen
+ 200;
107 new_buf
= realloc(*buf
, buflen
);
108 if (new_buf
== NULL
) {
116 *retlen
= 1 + snprintf(*buf
, buflen
,
117 "TEST from %s: %s v%s",
118 nodeinfo
.nodename
, args
,
123 case CLVMD_CMD_LOCK_VG
:
125 /* Check to see if the VG is in use by LVM1 */
126 status
= do_check_lvm1(lockname
);
127 /* P_#global causes a full cache refresh */
128 if (!strcmp(lockname
, "P_" VG_GLOBAL
))
131 drop_metadata(lockname
+ 2);
135 case CLVMD_CMD_LOCK_LV
:
136 /* This is the biggie */
137 lock_cmd
= args
[0] & 0x3F;
138 lock_flags
= args
[1];
140 status
= do_lock_lv(lock_cmd
, lock_flags
, lockname
);
141 /* Replace EIO with something less scary */
144 1 + snprintf(*buf
, buflen
, "%s",
145 get_last_lvm_error());
150 case CLVMD_CMD_LOCK_QUERY
:
154 if ((locktype
= do_lock_query(lockname
)))
155 *retlen
= 1 + snprintf(*buf
, buflen
, "%s", locktype
);
158 case CLVMD_CMD_REFRESH
:
162 case CLVMD_CMD_SET_DEBUG
:
166 case CLVMD_CMD_GET_CLUSTERNAME
:
167 status
= clops
->get_cluster_name(*buf
, buflen
);
169 *retlen
= strlen(*buf
)+1;
172 case CLVMD_CMD_VG_BACKUP
:
174 * Do not run backup on local node, caller should do that.
177 lvm_do_backup(&args
[2]);
181 /* Won't get here because command is validated in pre_command */
185 /* Check the status of the command and return the error text */
187 *retlen
= 1 + snprintf(*buf
, buflen
, "%s", strerror(status
));
194 static int lock_vg(struct local_client
*client
)
196 struct dm_hash_table
*lock_hash
;
197 struct clvm_header
*header
=
198 (struct clvm_header
*) client
->bits
.localsock
.cmd
;
199 unsigned char lock_cmd
;
200 unsigned char lock_flags
;
201 char *args
= header
->node
+ strlen(header
->node
) + 1;
206 /* Keep a track of VG locks in our own hash table. In current
207 practice there should only ever be more than two VGs locked
208 if a user tries to merge lots of them at once */
209 if (client
->bits
.localsock
.private) {
210 lock_hash
= (struct dm_hash_table
*)client
->bits
.localsock
.private;
213 lock_hash
= dm_hash_create(3);
216 client
->bits
.localsock
.private = (void *)lock_hash
;
219 lock_cmd
= args
[0] & 0x3F;
220 lock_flags
= args
[1];
222 DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname
, lock_cmd
, client
);
224 if (lock_cmd
== LCK_UNLOCK
) {
226 lkid
= (int)(long)dm_hash_lookup(lock_hash
, lockname
);
230 status
= sync_unlock(lockname
, lkid
);
234 dm_hash_remove(lock_hash
, lockname
);
237 /* Read locks need to be PR; other modes get passed through */
238 if ((lock_cmd
& LCK_TYPE_MASK
) == LCK_READ
) {
239 lock_cmd
&= ~LCK_TYPE_MASK
;
240 lock_cmd
|= LCK_PREAD
;
242 status
= sync_lock(lockname
, (int)lock_cmd
, (lock_flags
& LCK_NONBLOCK
) ? LKF_NOQUEUE
: 0, &lkid
);
246 dm_hash_insert(lock_hash
, lockname
, (void *)(long)lkid
);
253 /* Pre-command is a good place to get locks that are needed only for the duration
254 of the commands around the cluster (don't forget to free them in post-command),
255 and to sanity check the command arguments */
256 int do_pre_command(struct local_client
*client
)
258 struct clvm_header
*header
=
259 (struct clvm_header
*) client
->bits
.localsock
.cmd
;
260 unsigned char lock_cmd
;
261 unsigned char lock_flags
;
262 char *args
= header
->node
+ strlen(header
->node
) + 1;
267 switch (header
->cmd
) {
269 status
= sync_lock("CLVMD_TEST", LKM_EXMODE
, 0, &lockid
);
270 client
->bits
.localsock
.private = (void *)(long)lockid
;
273 case CLVMD_CMD_LOCK_VG
:
275 /* We take out a real lock unless LCK_CACHE was set */
276 if (!strncmp(lockname
, "V_", 2) ||
277 !strncmp(lockname
, "P_#", 3))
278 status
= lock_vg(client
);
281 case CLVMD_CMD_LOCK_LV
:
283 lock_flags
= args
[1];
285 status
= pre_lock_lv(lock_cmd
, lock_flags
, lockname
);
288 case CLVMD_CMD_REFRESH
:
289 case CLVMD_CMD_GET_CLUSTERNAME
:
290 case CLVMD_CMD_SET_DEBUG
:
291 case CLVMD_CMD_VG_BACKUP
:
292 case CLVMD_CMD_LOCK_QUERY
:
296 log_error("Unknown command %d received\n", header
->cmd
);
302 /* Note that the post-command routine is called even if the pre-command or the real command
304 int do_post_command(struct local_client
*client
)
306 struct clvm_header
*header
=
307 (struct clvm_header
*) client
->bits
.localsock
.cmd
;
309 unsigned char lock_cmd
;
310 unsigned char lock_flags
;
311 char *args
= header
->node
+ strlen(header
->node
) + 1;
314 switch (header
->cmd
) {
317 sync_unlock("CLVMD_TEST", (int) (long) client
->bits
.localsock
.private);
318 client
->bits
.localsock
.private = 0;
321 case CLVMD_CMD_LOCK_VG
:
322 case CLVMD_CMD_VG_BACKUP
:
323 case CLVMD_CMD_LOCK_QUERY
:
324 /* Nothing to do here */
327 case CLVMD_CMD_LOCK_LV
:
329 lock_flags
= args
[1];
331 status
= post_lock_lv(lock_cmd
, lock_flags
, lockname
);
338 /* Called when the client is about to be deleted */
339 void cmd_client_cleanup(struct local_client
*client
)
341 if (client
->bits
.localsock
.private) {
343 struct dm_hash_node
*v
;
344 struct dm_hash_table
*lock_hash
=
345 (struct dm_hash_table
*)client
->bits
.localsock
.private;
347 dm_hash_iterate(v
, lock_hash
) {
348 int lkid
= (int)(long)dm_hash_get_data(lock_hash
, v
);
349 char *lockname
= dm_hash_get_key(lock_hash
, v
);
351 DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname
, lkid
);
352 sync_unlock(lockname
, lkid
);
355 dm_hash_destroy(lock_hash
);
356 client
->bits
.localsock
.private = 0;