summaryrefslogtreecommitdiff
path: root/liblvm/lvm_base.c
blob: fce994cfdbaa8513e14629aa24544175b258bdd0 (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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
 * Copyright (C) 2008,2009 Red Hat, Inc. All rights reserved.
 *
 * 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 Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser 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 "lib.h"
#include "toolcontext.h"
#include "locking.h"
#include "lvm-version.h"
#include "metadata-exported.h"
#include "lvm2app.h"
#include "lvm_misc.h"

const char *lvm_library_get_version(void)
{
	return LVM_VERSION;
}

static lvm_t _lvm_init(const char *system_dir)
{
	struct cmd_context *cmd;

	/* FIXME: logging bound to handle
	 */

	if (!udev_init_library_context())
		stack;

	/*
	 * It's not necessary to use name mangling for LVM:
	 *   - the character set used for VG-LV names is subset of udev character set
	 *   - when we check other devices (e.g. device_is_usable fn), we use major:minor, not dm names
	 */
	dm_set_name_mangling_mode(DM_STRING_MANGLING_NONE);

	/* create context */
	/* FIXME: split create_toolcontext */
	/* FIXME: make all globals configurable */
	cmd = create_toolcontext(0, system_dir, 0, 0, 1, 1);
	if (!cmd)
		return NULL;

	/*
	 * FIXME: if an non memory error occured, return the cmd (maybe some
	 * cleanup needed).
	 */

	/* initialization from lvm_run_command */
	init_error_message_produced(0);

	/* FIXME: locking_type config option needed? */
	/* initialize locking */
	if (!init_locking(-1, cmd, 0)) {
		/* FIXME: use EAGAIN as error code here */
		lvm_quit((lvm_t) cmd);
		return NULL;
	}
	/*
	 * FIXME: Use cmd->cmd_line as audit trail for liblvm calls.  Used in
	 * archive() call.  Possible example:
	 * cmd_line = "lvm_vg_create: vg1\nlvm_vg_extend vg1 /dev/sda1\n"
	 */
	cmd->cmd_line = "liblvm";

	/*
	 * Turn off writing to stdout/stderr.
	 * FIXME Fix lib/ to support a non-interactive mode instead.
	 */
	log_suppress(1);

	return (lvm_t) cmd;
}


lvm_t lvm_init(const char *system_dir)
{
	lvm_t h = NULL;
	struct saved_env e = store_user_env(NULL);
	h = _lvm_init(system_dir);
	restore_user_env(&e);
	return h;
}

void lvm_quit(lvm_t libh)
{
	struct saved_env e = store_user_env((struct cmd_context *)libh);
	fin_locking();
	destroy_toolcontext((struct cmd_context *)libh);
	udev_fin_library_context();
	restore_user_env(&e);
}

int lvm_config_reload(lvm_t libh)
{
	int rc = 0;

	/* FIXME: re-init locking needed here? */
	struct saved_env e = store_user_env((struct cmd_context *)libh);
	if (!refresh_toolcontext((struct cmd_context *)libh))
		rc = -1;
	restore_user_env(&e);
	return rc;
}

/*
 * FIXME: submit a patch to document the --config option
 */
int lvm_config_override(lvm_t libh, const char *config_settings)
{
	int rc = 0;
	struct cmd_context *cmd = (struct cmd_context *)libh;
	struct saved_env e = store_user_env((struct cmd_context *)libh);

	if (!override_config_tree_from_string(cmd, config_settings))
		rc = -1;
	restore_user_env(&e);
	return rc;
}

/*
 * When full lvm connection is not being used, libh can be NULL
 * and this command will internally create a single-use, light-weight
 * cmd struct that only has cmd->cft populated from lvm.conf.
 */
int lvm_config_find_bool(lvm_t libh, const char *config_path, int fail)
{
	int rc = 0;
	struct cmd_context *cmd;
	struct saved_env e;

	if (libh) {
		cmd = (struct cmd_context *)libh;
		e = store_user_env((struct cmd_context *)libh);
	} else {
		if (!(cmd = create_config_context()))
			return 0;
	}

	rc = dm_config_tree_find_bool(cmd->cft, config_path, fail);

	if (libh)
		restore_user_env(&e);
	else
		destroy_config_context(cmd);
	return rc;
}

int lvm_errno(lvm_t libh)
{
	int rc;
	struct saved_env e = store_user_env((struct cmd_context *)libh);
	rc = stored_errno();
	restore_user_env(&e);
	return rc;
}

const char *lvm_errmsg(lvm_t libh)
{
	const char *rc = NULL;
	struct cmd_context *cmd = (struct cmd_context *)libh;
	struct saved_env e = store_user_env((struct cmd_context *)libh);

	const char *msg = stored_errmsg_with_clear();
	if (msg) {
		rc = dm_pool_strdup(cmd->mem, msg);
		free((void *)msg);
	}

	restore_user_env(&e);
	return rc;
}

const char *lvm_vgname_from_pvid(lvm_t libh, const char *pvid)
{
	const char *rc = NULL;
	struct cmd_context *cmd = (struct cmd_context *)libh;
	struct id id;
	struct saved_env e = store_user_env((struct cmd_context *)libh);

	if (id_read_format(&id, pvid)) {
		rc = find_vgname_from_pvid(cmd, (char *)id.uuid);
	} else {
		log_error(INTERNAL_ERROR "Unable to convert uuid");
	}

	restore_user_env(&e);
	return rc;
}

const char *lvm_vgname_from_device(lvm_t libh, const char *device)
{
	const char *rc = NULL;
	struct cmd_context *cmd = (struct cmd_context *)libh;
	struct saved_env e = store_user_env(cmd);
	rc = find_vgname_from_pvname(cmd, device);
	restore_user_env(&e);
	return rc;
}

/*
 * No context to work with, so no ability to save off and restore env is not
 * available and is not needed.
 */
float lvm_percent_to_float(percent_t v)
{
	return dm_percent_to_float(v);
}