summaryrefslogtreecommitdiff
path: root/daemons/lvmetad/testclient.c
blob: 2a43a7571ddac3d15219db894c51aaa39b602c0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * 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];
	id_write_format(dev->pvid, uuid, 64);
	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, 0);
		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;
}