| /* |
| * Copyright (C) 2011-2014 Red Hat, Inc. |
| * |
| * This file is part of LVM2. |
| * |
| * This copyrighted material is made available to anyone wishing to use, |
| * modify, copy, or redistribute it subject to the terms and conditions |
| * of the GNU General Public License v.2. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| #include "tool.h" |
| |
| #include "lvmetad-client.h" |
| #include "label.h" |
| #include "lvmcache.h" |
| #include "metadata.h" |
| |
| const char *uuid1 = "abcd-efgh"; |
| const char *uuid2 = "bbcd-efgh"; |
| const char *vgid = "yada-yada"; |
| const char *uuid3 = "cbcd-efgh"; |
| |
| const char *metadata2 = "{\n" |
| "id = \"yada-yada\"\n" |
| "seqno = 15\n" |
| "status = [\"READ\", \"WRITE\"]\n" |
| "flags = []\n" |
| "extent_size = 8192\n" |
| "physical_volumes {\n" |
| " pv0 {\n" |
| " id = \"abcd-efgh\"\n" |
| " }\n" |
| " pv1 {\n" |
| " id = \"bbcd-efgh\"\n" |
| " }\n" |
| " pv2 {\n" |
| " id = \"cbcd-efgh\"\n" |
| " }\n" |
| "}\n" |
| "}\n"; |
| |
| void _handle_reply(daemon_reply reply) { |
| const char *repl = daemon_reply_str(reply, "response", NULL); |
| const char *status = daemon_reply_str(reply, "status", NULL); |
| const char *vgid = daemon_reply_str(reply, "vgid", NULL); |
| |
| fprintf(stderr, "[C] REPLY: %s\n", repl); |
| if (!strcmp(repl, "failed")) |
| fprintf(stderr, "[C] REASON: %s\n", daemon_reply_str(reply, "reason", "unknown")); |
| if (vgid) |
| fprintf(stderr, "[C] VGID: %s\n", vgid); |
| if (status) |
| fprintf(stderr, "[C] STATUS: %s\n", status); |
| daemon_reply_destroy(reply); |
| } |
| |
| void _pv_add(daemon_handle h, const char *uuid, const char *metadata) |
| { |
| daemon_reply reply = daemon_send_simple(h, "pv_add", "uuid = %s", uuid, |
| "metadata = %b", metadata, |
| NULL); |
| _handle_reply(reply); |
| } |
| |
| int scan(daemon_handle h, char *fn) { |
| struct device *dev = dev_cache_get(fn, NULL); |
| |
| struct label *label; |
| if (!label_read(dev, &label, 0)) { |
| fprintf(stderr, "[C] no label found on %s\n", fn); |
| return; |
| } |
| |
| char uuid[64]; |
| if (!id_write_format(dev->pvid, uuid, 64)) { |
| fprintf(stderr, "[C] Failed to format PV UUID for %s", dev_name(dev)); |
| return; |
| } |
| fprintf(stderr, "[C] found PV: %s\n", uuid); |
| struct lvmcache_info *info = (struct lvmcache_info *) label->info; |
| struct physical_volume pv = { 0, }; |
| |
| if (!(info->fmt->ops->pv_read(info->fmt, dev_name(dev), &pv, 0))) { |
| fprintf(stderr, "[C] Failed to read PV %s", dev_name(dev)); |
| return; |
| } |
| |
| struct format_instance_ctx fic; |
| struct format_instance *fid = info->fmt->ops->create_instance(info->fmt, &fic); |
| struct metadata_area *mda; |
| struct volume_group *vg = NULL; |
| dm_list_iterate_items(mda, &info->mdas) { |
| struct volume_group *this = mda->ops->vg_read(fid, "", mda); |
| if (this && !vg || this->seqno > vg->seqno) |
| vg = this; |
| } |
| if (vg) { |
| char *buf = NULL; |
| /* TODO. This is not entirely correct, since export_vg_to_buffer |
| * adds trailing garbage to the buffer. We may need to use |
| * export_vg_to_config_tree and format the buffer ourselves. It |
| * does, however, work for now, since the garbage is well |
| * formatted and has no conflicting keys with the rest of the |
| * request. */ |
| export_vg_to_buffer(vg, &buf); |
| daemon_reply reply = |
| daemon_send_simple(h, "pv_add", "uuid = %s", uuid, |
| "metadata = %b", strchr(buf, '{'), |
| NULL); |
| _handle_reply(reply); |
| } |
| } |
| |
| void _dump_vg(daemon_handle h, const char *uuid) |
| { |
| daemon_reply reply = daemon_send_simple(h, "vg_by_uuid", "uuid = %s", uuid, NULL); |
| fprintf(stderr, "[C] reply buffer: %s\n", reply.buffer); |
| daemon_reply_destroy(reply); |
| } |
| |
| int main(int argc, char **argv) { |
| daemon_handle h = lvmetad_open(); |
| /* FIXME Missing error path */ |
| |
| if (argc > 1) { |
| int i; |
| struct cmd_context *cmd = create_toolcontext(0, NULL, 0, 0, 1, 1); |
| for (i = 1; i < argc; ++i) { |
| const char *uuid = NULL; |
| scan(h, argv[i]); |
| } |
| destroy_toolcontext(cmd); |
| /* FIXME Missing lvmetad_close() */ |
| return 0; |
| } |
| |
| _pv_add(h, uuid1, NULL); |
| _pv_add(h, uuid2, metadata2); |
| _dump_vg(h, vgid); |
| _pv_add(h, uuid3, NULL); |
| |
| daemon_close(h); /* FIXME lvmetad_close? */ |
| return 0; |
| } |