static int do_drop(void) { daemon_reply reply; int result; int rv; syslog(LOG_WARNING, "Dropping locks for VG %s.", arg_vg_name); /* * Check for misuse by looking for any active LVs in the VG * and refusing this operation if found? One possible way * to kill LVs (e.g. if fs cannot be unmounted) is to suspend * them, or replace them with the error target. In that * case the LV will still appear to be active, but it is * safe to release the lock. */ reply = _lvmlockd_send("drop_vg", "cmd = %s", "lvmlockctl", "pid = " FMTd64, (int64_t) getpid(), "vg_name = %s", arg_vg_name, NULL); if (!_lvmlockd_result(reply, &result)) { log_error("lvmlockd result %d", result); rv = result; } else { rv = 0; } daemon_reply_destroy(reply); return rv; }
static int do_stop_lockspaces(void) { daemon_reply reply; char opts[32]; int result; int rv; memset(opts, 0, sizeof(opts)); if (wait_opt) strcat(opts, "wait "); if (force_opt) strcat(opts, "force "); reply = _lvmlockd_send("stop_all", "cmd = %s", "lvmlockctl", "pid = " FMTd64, (int64_t) getpid(), "opts = %s", opts[0] ? opts : "none", NULL); if (!_lvmlockd_result(reply, &result)) { log_error("lvmlockd result %d", result); rv = result; } else { rv = 0; } daemon_reply_destroy(reply); return rv; }
static int do_dump(const char *req_name) { daemon_reply reply; int result; int fd, rv = 0; int count = 0; fd = setup_dump_socket(); if (fd < 0) { log_error("socket error %d", fd); return fd; } reply = daemon_send_simple(_lvmlockd, req_name, NULL); if (reply.error) { log_error("reply error %d", reply.error); rv = reply.error; goto out; } result = daemon_reply_int(reply, "result", 0); dump_len = daemon_reply_int(reply, "dump_len", 0); daemon_reply_destroy(reply); if (result < 0) { rv = result; log_error("result %d", result); } if (!dump_len) goto out; memset(dump_buf, 0, sizeof(dump_buf)); retry: rv = recvfrom(fd, dump_buf + count, dump_len - count, MSG_WAITALL, (struct sockaddr *)&dump_addr, &dump_addrlen); if (rv < 0) { log_error("recvfrom error %d %d", rv, errno); rv = -errno; goto out; } count += rv; if (count < dump_len) goto retry; rv = 0; if ((info && dump) || !strcmp(req_name, "dump")) printf("%s\n", dump_buf); else format_info(); out: if (close(fd)) log_error("failed to close dump socket %d", fd); return rv; }
static int do_quit(void) { daemon_reply reply; int rv = 0; reply = daemon_send_simple(_lvmlockd, "quit", NULL); if (reply.error) { log_error("reply error %d", reply.error); rv = reply.error; } daemon_reply_destroy(reply); return rv; }
static int do_kill(void) { daemon_reply reply; int result; int rv; syslog(LOG_EMERG, "Lost access to sanlock lease storage in VG %s.", arg_vg_name); /* These two lines explain the manual alternative to the FIXME below. */ syslog(LOG_EMERG, "Immediately deactivate LVs in VG %s.", arg_vg_name); syslog(LOG_EMERG, "Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name); /* * It may not be strictly necessary to notify lvmlockd of the kill, but * lvmlockd can use this information to avoid attempting any new lock * requests in the VG (which would fail anyway), and can return an * error indicating that the VG has been killed. */ reply = _lvmlockd_send("kill_vg", "cmd = %s", "lvmlockctl", "pid = " FMTd64, (int64_t) getpid(), "vg_name = %s", arg_vg_name, NULL); if (!_lvmlockd_result(reply, &result)) { log_error("lvmlockd result %d", result); rv = result; } else { rv = 0; } daemon_reply_destroy(reply); /* * FIXME: here is where we should implement a strong form of * blkdeactivate, and if it completes successfully, automatically call * do_drop() afterward. (The drop step may not always be necessary * if the lvm commands run while shutting things down release all the * leases.) * * run_strong_blkdeactivate(); * do_drop(); */ return rv; }
static int do_able(const char *req_name) { daemon_reply reply; int result; int rv; reply = _lvmlockd_send(req_name, "cmd = %s", "lvmlockctl", "pid = " FMTd64, (int64_t) getpid(), "vg_name = %s", arg_vg_name, NULL); if (!_lvmlockd_result(reply, &result)) { log_error("lvmlockd result %d", result); rv = result; } else { rv = 0; } daemon_reply_destroy(reply); return rv; }
int main(int argc, char **argv) { daemon_reply reply; char *cmd; char *uuid; char *name; int val; int ver; if (argc < 2) { printf("lvmetactl dump\n"); printf("lvmetactl pv_list\n"); printf("lvmetactl vg_list\n"); printf("lvmetactl vg_lookup_name <name>\n"); printf("lvmetactl vg_lookup_uuid <uuid>\n"); printf("lvmetactl pv_lookup_uuid <uuid>\n"); printf("lvmetactl set_global_invalid 0|1\n"); printf("lvmetactl get_global_invalid\n"); printf("lvmetactl set_vg_version <uuid> <name> <version>\n"); printf("lvmetactl vg_lock_type <uuid>\n"); return -1; } cmd = argv[1]; h = lvmetad_open(NULL); if (!strcmp(cmd, "dump")) { reply = daemon_send_simple(h, "dump", "token = %s", "skip", NULL); printf("%s\n", reply.buffer.mem); } else if (!strcmp(cmd, "pv_list")) { reply = daemon_send_simple(h, "pv_list", "token = %s", "skip", NULL); printf("%s\n", reply.buffer.mem); } else if (!strcmp(cmd, "vg_list")) { reply = daemon_send_simple(h, "vg_list", "token = %s", "skip", NULL); printf("%s\n", reply.buffer.mem); } else if (!strcmp(cmd, "set_global_invalid")) { if (argc < 3) { printf("set_global_invalid 0|1\n"); return -1; } val = atoi(argv[2]); reply = daemon_send_simple(h, "set_global_info", "global_invalid = %d", val, "token = %s", "skip", NULL); print_reply(reply); } else if (!strcmp(cmd, "get_global_invalid")) { reply = daemon_send_simple(h, "get_global_info", "token = %s", "skip", NULL); printf("%s\n", reply.buffer.mem); } else if (!strcmp(cmd, "set_vg_version")) { if (argc < 5) { printf("set_vg_version <uuid> <name> <ver>\n"); return -1; } uuid = argv[2]; name = argv[3]; ver = atoi(argv[4]); if ((strlen(uuid) == 1) && (uuid[0] == '-')) uuid = NULL; if ((strlen(name) == 1) && (name[0] == '-')) name = NULL; if (uuid && name) { reply = daemon_send_simple(h, "set_vg_info", "uuid = %s", uuid, "name = %s", name, "version = %d", ver, "token = %s", "skip", NULL); } else if (uuid) { reply = daemon_send_simple(h, "set_vg_info", "uuid = %s", uuid, "version = %d", ver, "token = %s", "skip", NULL); } else if (name) { reply = daemon_send_simple(h, "set_vg_info", "name = %s", name, "version = %d", ver, "token = %s", "skip", NULL); } else { printf("name or uuid required\n"); return -1; } print_reply(reply); } else if (!strcmp(cmd, "vg_lookup_name")) { if (argc < 3) { printf("vg_lookup_name <name>\n"); return -1; } name = argv[2]; reply = daemon_send_simple(h, "vg_lookup", "name = %s", name, "token = %s", "skip", NULL); printf("%s\n", reply.buffer.mem); } else if (!strcmp(cmd, "vg_lookup_uuid")) { if (argc < 3) { printf("vg_lookup_uuid <uuid>\n"); return -1; } uuid = argv[2]; reply = daemon_send_simple(h, "vg_lookup", "uuid = %s", uuid, "token = %s", "skip", NULL); printf("%s\n", reply.buffer.mem); } else if (!strcmp(cmd, "vg_lock_type")) { struct dm_config_node *metadata; const char *lock_type; if (argc < 3) { printf("vg_lock_type <uuid>\n"); return -1; } uuid = argv[2]; reply = daemon_send_simple(h, "vg_lookup", "uuid = %s", uuid, "token = %s", "skip", NULL); /* printf("%s\n", reply.buffer.mem); */ metadata = dm_config_find_node(reply.cft->root, "metadata"); if (!metadata) { printf("no metadata\n"); goto out; } lock_type = dm_config_find_str(metadata, "metadata/lock_type", NULL); if (!lock_type) { printf("no lock_type\n"); goto out; } printf("lock_type %s\n", lock_type); } else if (!strcmp(cmd, "pv_lookup_uuid")) { if (argc < 3) { printf("pv_lookup_uuid <uuid>\n"); return -1; } uuid = argv[2]; reply = daemon_send_simple(h, "pv_lookup", "uuid = %s", uuid, "token = %s", "skip", NULL); printf("%s\n", reply.buffer.mem); } else { printf("unknown command\n"); goto out_close; } out: daemon_reply_destroy(reply); out_close: daemon_close(h); return 0; }