mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
7f97c7ea9a
As we start refactoring the code to break dependencies (see doc/refactoring.txt), I want us to use full paths in the includes (eg, #include "base/data-struct/list.h"). This makes it more obvious when we're breaking abstraction boundaries, eg, including a file in metadata/ from base/
148 lines
4.1 KiB
C
148 lines
4.1 KiB
C
/*
|
|
* 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 "tools/tool.h"
|
|
|
|
#include "daemons/lvmetad/lvmetad-client.h"
|
|
#include "lib/label/label.h"
|
|
#include "lib/cache/lvmcache.h"
|
|
#include "lib/metadata/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;
|
|
}
|