master - lvmetad: Fix the fix for 813766 (lvmetad connection warning).
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d6d207006a8f33...
Commit: d6d207006a8f337e9d6919ffddedfa08dac128c6
Parent: f2a5d3ae3a457059bc7de7cf3fce8eb092ac03dd
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Fri Oct 12 11:16:38 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Fri Oct 12 11:22:47 2012 +0200
lvmetad: Fix the fix for 813766 (lvmetad connection warning).
---
lib/cache/lvmetad.c | 5 +++--
test/shell/lvmetad-warning.sh | 27 +++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index b1c799a..47a6d75 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -55,8 +55,9 @@ void lvmetad_init(struct cmd_context *cmd)
void lvmetad_warning()
{
- log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to internal scanning.",
- strerror(_lvmetad.error));
+ if (_lvmetad_use && (_lvmetad.socket_fd < 0 || _lvmetad.error))
+ log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to internal scanning.",
+ strerror(_lvmetad.error));
}
int lvmetad_active(void)
diff --git a/test/shell/lvmetad-warning.sh b/test/shell/lvmetad-warning.sh
new file mode 100644
index 0000000..3a97a1b
--- /dev/null
+++ b/test/shell/lvmetad-warning.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+. lib/test
+
+test -e LOCAL_LVMETAD || skip
+aux prepare_pvs 2
+
+vgcreate $vg1 $dev1 $dev2
+lvchange -ay $vg1 2>&1 | not grep "Failed to connect"
+kill $(cat LOCAL_LVMETAD)
+lvchange -ay $vg1 2>&1 | grep "Failed to connect"
+lvchange -ay $vg1 --sysinit 2>&1 | not grep "Failed to connect"
+aux lvmconf 'global/use_lvmetad = 0'
+lvchange -ay $vg1 2>&1 | not grep "Failed to connect"
+lvchange -ay $vg1 --sysinit 2>&1 | not grep "Failed to connect"
+aux prepare_lvmetad
+lvchange -ay $vg1 2>&1 | not grep "Failed to connect"
+lvchange -ay $vg1 --sysinit 2>&1 | not grep "Failed to connect"
11 years, 6 months
master - lvmetad: validate dm_asprintf in buffer_append_vf
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f2a5d3ae3a4570...
Commit: f2a5d3ae3a457059bc7de7cf3fce8eb092ac03dd
Parent: 5c792f620b3448a6bbbe7dc10f9210ad3383d977
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Oct 12 10:57:01 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Oct 12 10:59:10 2012 +0200
lvmetad: validate dm_asprintf in buffer_append_vf
Check result of dm_asprintf
Check buffer_append result
Declare vars in front
---
libdaemon/client/config-util.c | 33 ++++++++++++++++++++-------------
1 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/libdaemon/client/config-util.c b/libdaemon/client/config-util.c
index a65a2cc..8a6dced 100644
--- a/libdaemon/client/config-util.c
+++ b/libdaemon/client/config-util.c
@@ -23,9 +23,12 @@
int buffer_append_vf(struct buffer *buf, va_list ap)
{
- char *append;
+ char *append = NULL;
char *next;
int keylen;
+ int64_t value;
+ char *string;
+ char *block;
while ((next = va_arg(ap, char *))) {
if (!strchr(next, '=')) {
@@ -34,21 +37,25 @@ int buffer_append_vf(struct buffer *buf, va_list ap)
}
keylen = strchr(next, '=') - next;
if (strstr(next, "%d") || strstr(next, "%" PRId64)) {
- int64_t value = va_arg(ap, int64_t);
- dm_asprintf(&append, "%.*s= %" PRId64 "\n", keylen, next, value);
+ value = va_arg(ap, int64_t);
+ if (!dm_asprintf(&append, "%.*s= %" PRId64 "\n", keylen, next, value) < 0)
+ goto fail;
} else if (strstr(next, "%s")) {
- char *value = va_arg(ap, char *);
- dm_asprintf(&append, "%.*s= \"%s\"\n", keylen, next, value);
+ string = va_arg(ap, char *);
+ if (!dm_asprintf(&append, "%.*s= \"%s\"\n", keylen, next, string) < 0)
+ goto fail;
} else if (strstr(next, "%b")) {
- char *block = va_arg(ap, char *);
- if (!block)
+ if (!(block = va_arg(ap, char *)))
continue;
- dm_asprintf(&append, "%.*s%s", keylen, next, block);
- } else {
- dm_asprintf(&append, "%s", next);
- }
- if (!append) goto fail;
- buffer_append(buf, append);
+ if (!dm_asprintf(&append, "%.*s%s", keylen, next, block) < 0)
+ goto fail;
+ } else if (!dm_asprintf(&append, "%s", next) < 0)
+ goto fail;
+
+ if (!append ||
+ !buffer_append(buf, append))
+ return 0;
+
dm_free(append);
}
11 years, 6 months
master - lvmetad: check result of buffer_realloc
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5c792f620b3448...
Commit: 5c792f620b3448a6bbbe7dc10f9210ad3383d977
Parent: c4dcbf67a3d19bf4a91b4b72e3e230583a8ee2da
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Oct 12 10:50:07 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Oct 12 10:59:10 2012 +0200
lvmetad: check result of buffer_realloc
---
libdaemon/client/config-util.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/libdaemon/client/config-util.c b/libdaemon/client/config-util.c
index 8aa9ed2..a65a2cc 100644
--- a/libdaemon/client/config-util.c
+++ b/libdaemon/client/config-util.c
@@ -289,8 +289,9 @@ int buffer_append(struct buffer *buf, const char *string)
{
int len = strlen(string);
- if (buf->allocated - buf->used <= len)
- buffer_realloc(buf, len + 1);
+ if ((buf->allocated - buf->used <= len) &&
+ !buffer_realloc(buf, len + 1))
+ return 0;
strcpy(buf->mem + buf->used, string);
buf->used += len;
11 years, 6 months
master - lvmetad: initialize cft value
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c4dcbf67a3d19b...
Commit: c4dcbf67a3d19bf4a91b4b72e3e230583a8ee2da
Parent: 28776b9526784fc3dd2ab94a4151613771c4dfda
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Oct 12 10:35:01 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Oct 12 10:59:10 2012 +0200
lvmetad: initialize cft value
the error should not test garbage value.
---
daemons/lvmetad/lvmetad-core.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 8540273..9a5c8b9 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -663,7 +663,7 @@ static int vg_remove_if_missing(lvmetad_state *s, const char *vgid)
static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid,
struct dm_config_node *metadata, int64_t *oldseq)
{
- struct dm_config_tree *cft;
+ struct dm_config_tree *cft = NULL;
struct dm_config_tree *old;
int retval = 0;
int seq;
11 years, 6 months
master - lvmetad: Make --sysinit suppress connection failure warnings.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=28776b9526784f...
Commit: 28776b9526784fc3dd2ab94a4151613771c4dfda
Parent: 9ee071705b2c35e1132f39f5731861c831a1bb6b
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Fri Oct 12 02:48:39 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Fri Oct 12 10:58:04 2012 +0200
lvmetad: Make --sysinit suppress connection failure warnings.
---
lib/cache/lvmetad.c | 9 +++++++--
lib/cache/lvmetad.h | 4 ++++
tools/lvmcmdline.c | 3 +++
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 5d211c6..b1c799a 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -49,11 +49,16 @@ void lvmetad_init(struct cmd_context *cmd)
if (_lvmetad.socket_fd >= 0 && !_lvmetad.error) {
_lvmetad_connected = 1;
_lvmetad_cmd = cmd;
- } else
- log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to internal scanning.", strerror(_lvmetad.error));
+ }
}
}
+void lvmetad_warning()
+{
+ log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to internal scanning.",
+ strerror(_lvmetad.error));
+}
+
int lvmetad_active(void)
{
return _lvmetad_use && _lvmetad_connected;
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index 10c4b13..f6e7b67 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -48,6 +48,9 @@ void lvmetad_set_socket(const char *);
*/
int lvmetad_active(void);
+/* Print a warning if lvmetad is enabled but we failed to connect. */
+void lvmetad_warning(void);
+
/*
* Drop connection to lvmetad. A subsequent lvmetad_init() will re-establish
* the connection (possibly at a different socket path).
@@ -137,6 +140,7 @@ int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler)
# define lvmetad_set_active(a) do { } while (0)
# define lvmetad_set_socket(a) do { } while (0)
# define lvmetad_active() (0)
+# define lvmetad_warning() do { } while (0)
# define lvmetad_set_token(a) do { } while (0)
# define lvmetad_vg_update(vg) (1)
# define lvmetad_vg_remove(vg) (1)
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index bccf7a6..efcefe3 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -876,6 +876,9 @@ static int _get_settings(struct cmd_context *cmd)
else
init_ignorelockingfailure(0);
+ if (!arg_count(cmd, sysinit_ARG))
+ lvmetad_warning();
+
if (arg_count(cmd, nosuffix_ARG))
cmd->current_settings.suffix = 0;
11 years, 6 months
master - cleanup: fix compiler warnings
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9ee071705b2c35...
Commit: 9ee071705b2c35e1132f39f5731861c831a1bb6b
Parent: ee3cfa41843b0af1ef220ecf8bf6db82676af8c8
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Oct 12 10:15:30 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Oct 12 10:25:07 2012 +0200
cleanup: fix compiler warnings
remove unused vars
move var declarations into the front of functions.
fix some sign warnings
---
daemons/lvmetad/lvmetad-core.c | 1 -
lib/cache/lvmetad.c | 12 ++++++------
lib/commands/toolcontext.c | 4 +++-
lib/metadata/metadata.c | 2 +-
lib/metadata/raid_manip.c | 4 +---
libdaemon/client/config-util.c | 21 ++++++++++++++-------
libdaemon/client/daemon-client.c | 13 ++++++++++---
libdaemon/server/daemon-log.c | 23 ++++++++++++++++-------
libdaemon/server/daemon-server.c | 5 +++--
9 files changed, 54 insertions(+), 31 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 99ae99f..8540273 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -1147,7 +1147,6 @@ int main(int argc, char *argv[])
signed char opt;
daemon_state s = { .private = NULL };
lvmetad_state ls;
- int _restart = 0;
int _socket_override = 1;
s.name = "lvmetad";
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 18794be..5d211c6 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -66,13 +66,16 @@ void lvmetad_set_active(int active)
void lvmetad_set_token(const struct dm_config_value *filter)
{
+ int ft = 0;
+
if (_lvmetad_token)
dm_free(_lvmetad_token);
- int ft = 0;
+
while (filter && filter->type == DM_CFG_STRING) {
ft = calc_crc(ft, (const uint8_t *) filter->v.str, strlen(filter->v.str));
filter = filter->next;
}
+
if (!dm_asprintf(&_lvmetad_token, "filter:%u", ft))
log_warn("WARNING: Failed to set lvmetad token. Out of memory?");
}
@@ -84,7 +87,7 @@ void lvmetad_set_socket(const char *sock)
static daemon_reply _lvmetad_send(const char *id, ...);
-static int _token_update()
+static int _token_update(void)
{
daemon_reply repl = _lvmetad_send("token_update", NULL);
@@ -101,7 +104,7 @@ static int _token_update()
static daemon_reply _lvmetad_send(const char *id, ...)
{
va_list ap;
- daemon_reply repl, token_set;
+ daemon_reply repl;
daemon_request req;
int try = 0;
@@ -128,7 +131,6 @@ retry:
}
}
-out:
return repl;
}
@@ -589,7 +591,6 @@ static int _extract_mda(struct metadata_area *mda, void *baton)
{
struct _extract_mda_baton *b = baton;
struct dm_config_node *cn;
- int result = 0;
char id[32];
if (!mda->ops->mda_export_text) /* do nothing */
@@ -651,7 +652,6 @@ int lvmetad_pv_found(struct id pvid, struct device *device, const struct format_
char uuid[64];
daemon_reply reply;
struct lvmcache_info *info;
- const char *mdas = NULL;
struct dm_config_tree *pvmeta, *vgmeta;
const char *status;
int result;
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index c5e0ee3..5177f41 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -236,6 +236,7 @@ static int _process_config(struct cmd_context *cmd)
const struct dm_config_node *cn;
const struct dm_config_value *cv;
int64_t pv_min_kb;
+ const char *lvmetad_socket;
/* umask */
cmd->default_settings.umask = find_config_tree_int(cmd,
@@ -400,7 +401,8 @@ static int _process_config(struct cmd_context *cmd)
DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION));
lvmetad_disconnect();
- const char *lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
+
+ lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
if (!lvmetad_socket)
lvmetad_socket = DEFAULT_RUN_DIR "/lvmetad.socket";
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 220e0c1..5a633b6 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2943,7 +2943,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
struct pv_list *pvl, *pvl2;
struct dm_list all_pvs;
char uuid[64] __attribute__((aligned(8)));
- int seqno = 0;
+ unsigned seqno = 0;
if (is_orphan_vg(vgname)) {
if (use_precommitted) {
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 98a7db3..c7910e8 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -1136,7 +1136,6 @@ int lv_raid_change_image_count(struct logical_volume *lv,
int lv_raid_split(struct logical_volume *lv, const char *split_name,
uint32_t new_count, struct dm_list *splittable_pvs)
{
- const char *old_name;
struct lv_list *lvl;
struct dm_list removal_list, data_list;
struct cmd_context *cmd = lv->vg->cmd;
@@ -1207,7 +1206,6 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
dm_list_iterate_items(lvl, &data_list)
break;
- old_name = lvl->lv->name;
lvl->lv->name = split_name;
if (!vg_write(lv->vg)) {
@@ -1317,7 +1315,7 @@ int lv_raid_split_and_track(struct logical_volume *lv,
break;
}
- if (s >= seg->area_count) {
+ if (s >= (int) seg->area_count) {
log_error("Unable to find image to satisfy request");
return 0;
}
diff --git a/libdaemon/client/config-util.c b/libdaemon/client/config-util.c
index 30fc4f8..8aa9ed2 100644
--- a/libdaemon/client/config-util.c
+++ b/libdaemon/client/config-util.c
@@ -23,7 +23,7 @@
int buffer_append_vf(struct buffer *buf, va_list ap)
{
- char *append, *old;
+ char *append;
char *next;
int keylen;
@@ -60,10 +60,13 @@ fail:
int buffer_append_f(struct buffer *buf, ...)
{
+ int res;
va_list ap;
+
va_start(ap, buf);
- int res = buffer_append_vf(buf, ap);
+ res = buffer_append_vf(buf, ap);
va_end(ap);
+
return res;
}
@@ -203,10 +206,12 @@ struct dm_config_node *config_make_nodes_v(struct dm_config_tree *cft,
{
const char *next;
struct dm_config_node *first = NULL;
+ struct dm_config_node *cn;
+ const char *fmt, *key;
while ((next = va_arg(ap, char *))) {
- struct dm_config_node *cn = NULL;
- const char *fmt = strchr(next, '=');
+ cn = NULL;
+ fmt = strchr(next, '=');
if (!fmt) {
log_error(INTERNAL_ERROR "Bad format string '%s'", fmt);
@@ -214,7 +219,7 @@ struct dm_config_node *config_make_nodes_v(struct dm_config_tree *cft,
}
fmt += 2;
- char *key = dm_pool_strdup(cft->mem, next);
+ key = dm_pool_strdup(cft->mem, next);
*strchr(key, '=') = 0;
if (!strcmp(fmt, "%d") || !strcmp(fmt, "%" PRId64)) {
@@ -250,10 +255,13 @@ struct dm_config_node *config_make_nodes(struct dm_config_tree *cft,
struct dm_config_node *pre_sib,
...)
{
+ struct dm_config_node *res;
va_list ap;
+
va_start(ap, pre_sib);
- struct dm_config_node *res = config_make_nodes_v(cft, parent, pre_sib, ap);
+ res = config_make_nodes_v(cft, parent, pre_sib, ap);
va_end(ap);
+
return res;
}
@@ -280,7 +288,6 @@ int buffer_realloc(struct buffer *buf, int needed)
int buffer_append(struct buffer *buf, const char *string)
{
int len = strlen(string);
- char *new;
if (buf->allocated - buf->used <= len)
buffer_realloc(buf, len + 1);
diff --git a/libdaemon/client/daemon-client.c b/libdaemon/client/daemon-client.c
index 107882b..c4422d6 100644
--- a/libdaemon/client/daemon-client.c
+++ b/libdaemon/client/daemon-client.c
@@ -71,9 +71,10 @@ error:
daemon_reply daemon_send(daemon_handle h, daemon_request rq)
{
+ struct buffer buffer;
daemon_reply reply = { .cft = NULL, .error = 0 };
assert(h.socket_fd >= 0);
- struct buffer buffer = rq.buffer;
+ buffer = rq.buffer;
if (!buffer.mem)
dm_config_write_node(rq.cft->root, buffer_line, &buffer);
@@ -120,10 +121,13 @@ daemon_reply daemon_send_simple_v(daemon_handle h, const char *id, va_list ap)
daemon_reply daemon_send_simple(daemon_handle h, const char *id, ...)
{
+ daemon_reply r;
va_list ap;
+
va_start(ap, id);
- daemon_reply r = daemon_send_simple_v(h, id, ap);
+ r = daemon_send_simple_v(h, id, ap);
va_end(ap);
+
return r;
}
@@ -165,10 +169,13 @@ int daemon_request_extend_v(daemon_request r, va_list ap)
int daemon_request_extend(daemon_request r, ...)
{
+ int res;
va_list ap;
+
va_start(ap, r);
- int res = daemon_request_extend_v(r, ap);
+ res = daemon_request_extend_v(r, ap);
va_end(ap);
+
return res;
}
diff --git a/libdaemon/server/daemon-log.c b/libdaemon/server/daemon-log.c
index b31bb4e..1e1c9e0 100644
--- a/libdaemon/server/daemon-log.c
+++ b/libdaemon/server/daemon-log.c
@@ -10,15 +10,18 @@ struct backend {
static void log_syslog(log_state *s, void **state, int type, const char *message)
{
+ int prio;
+
if (!*state) { /* initialize */
*state = (void *)1;
openlog(s->name, LOG_PID, LOG_DAEMON);
}
- int prio = LOG_DEBUG;
+
switch (type) {
case DAEMON_LOG_INFO: prio = LOG_INFO; break;
case DAEMON_LOG_WARN: prio = LOG_WARNING; break;
case DAEMON_LOG_FATAL: prio = LOG_CRIT; break;
+ default: prio = LOG_DEBUG; break;
}
syslog(prio, "%s", message);
@@ -26,12 +29,14 @@ static void log_syslog(log_state *s, void **state, int type, const char *message
static void log_stderr(log_state *s, void **state, int type, const char *message)
{
- const char *prefix = "";
+ const char *prefix;
+
switch (type) {
case DAEMON_LOG_INFO: prefix = "I: "; break;
case DAEMON_LOG_WARN: prefix = "W: " ; break;
- case DAEMON_LOG_ERROR:
+ case DAEMON_LOG_ERROR: /* fall through */
case DAEMON_LOG_FATAL: prefix = "E: " ; break;
+ default: prefix = ""; break;
}
fprintf(stderr, "%s%s\n", prefix, message);
@@ -88,21 +93,25 @@ static int _log_line(const char *line, void *baton) {
void daemon_log_cft(log_state *s, int type, const char *prefix, const struct dm_config_node *n)
{
+ struct log_line_baton b = { .s = s, .type = type, .prefix = prefix };
+
if (!_type_interesting(s, type))
return;
- struct log_line_baton b = { .s = s, .type = type, .prefix = prefix };
dm_config_write_node(n, &_log_line, &b);
}
void daemon_log_multi(log_state *s, int type, const char *prefix, const char *msg)
{
+ struct log_line_baton b = { .s = s, .type = type, .prefix = prefix };
+ char *buf;
+ char *pos;
+
if (!_type_interesting(s, type))
return;
- struct log_line_baton b = { .s = s, .type = type, .prefix = prefix };
- char *buf = dm_strdup(msg);
- char *pos = buf;
+ buf = dm_strdup(msg);
+ pos = buf;
if (!buf)
return; /* _0 */
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 051e7c2..b02621f 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -356,13 +356,13 @@ struct thread_baton {
static response builtin_handler(daemon_state s, client_handle h, request r)
{
const char *rq = daemon_request_str(r, "request", "NONE");
+ response res = { .error = EPROTO };
if (!strcmp(rq, "hello")) {
return daemon_reply_simple("OK", "protocol = %s", s.protocol ?: "default",
"version = %" PRId64, (int64_t) s.protocol_version, NULL);
}
- response res = { .error = EPROTO };
buffer_init(&res.buffer);
return res;
}
@@ -444,6 +444,8 @@ static int handle_connect(daemon_state s)
void daemon_start(daemon_state s)
{
int failed = 0;
+ log_state _log = { { 0 } };
+
/*
* Switch to C locale to avoid reading large locale-archive file used by
* some glibc (on some distributions it takes over 100MB). Some daemons
@@ -459,7 +461,6 @@ void daemon_start(daemon_state s)
if (!s.foreground)
_daemonise();
- log_state _log = { { 0 } };
s.log = &_log;
s.log->name = s.name;
11 years, 6 months
master - python: Add bindings for liblvm2app.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ee3cfa41843b0a...
Commit: ee3cfa41843b0af1ef220ecf8bf6db82676af8c8
Parent: 4022fd3e79099fb22b2b7d3d6dca8de733a2a783
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Fri Oct 12 02:08:47 2012 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Fri Oct 12 02:08:47 2012 +0100
python: Add bindings for liblvm2app.
Use configure --enable-python_bindings to generate them.
Note that the Makefiles do not yet control the owner or permissions of
the two new files on installation.
---
Makefile.in | 17 +-
WHATS_NEW | 1 +
configure | 216 ++++++-
configure.in | 40 ++
lib/misc/configure.h.in | 3 -
make.tmpl.in | 3 +
python/Makefile.in | 39 ++
python/example.py | 125 ++++
python/liblvm.c | 1711 +++++++++++++++++++++++++++++++++++++++++++++++
python/setup.py.in | 35 +
10 files changed, 2175 insertions(+), 15 deletions(-)
diff --git a/Makefile.in b/Makefile.in
index 6b153d3..bbfcf2c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -32,13 +32,17 @@ ifeq ("@APPLIB@", "yes")
SUBDIRS += liblvm
endif
+ifeq ("@PYTHON_BINDINGS@", "yes")
+ SUBDIRS += python
+endif
+
SUBDIRS += scripts
# FIXME Should use intermediate Makefiles here!
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS = doc include man test scripts \
libdaemon lib tools daemons libdm \
- udev po liblvm \
+ udev po liblvm python \
unit-tests/datastruct unit-tests/mm unit-tests/regex
endif
DISTCLEAN_DIRS += lcov_reports*
@@ -69,6 +73,10 @@ po.pofile: tools.pofile daemons.pofile
pofile: po.pofile
endif
+ifeq ("@PYTHON_BINDINGS@", "yes")
+python: liblvm
+endif
+
ifneq ("$(CFLOW_CMD)", "")
tools.cflow: libdm.cflow lib.cflow
daemons.cflow: tools.cflow
@@ -103,6 +111,11 @@ install_systemd_generators:
install_systemd_units:
$(MAKE) -C scripts install_systemd_units
+ifeq ("@PYTHON_BINDINGS@", "yes")
+install_python_bindings:
+ $(MAKE) -C liblvm/python install_python_bindings
+endif
+
install_tmpfiles_configuration:
$(MAKE) -C scripts install_tmpfiles_configuration
@@ -148,7 +161,7 @@ ifeq ("$(TESTING)", "yes")
# testing and report generation
RUBY=ruby1.9 -Ireport-generators/lib -Ireport-generators/test
-.PHONEY: unit-test ruby-test test-programs
+.PHONY: unit-test ruby-test test-programs
# FIXME: put dependencies on libdm and liblvm
# FIXME: Should be handled by Makefiles in subdirs, not here at top level.
diff --git a/WHATS_NEW b/WHATS_NEW
index d614270..e419a46 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.98 -
=================================
+ Add configure --enable-python_bindings for liblvm2app to new python subdir.
Add implementation of lvm2api function lvm_percent_to_float.
Allow non power of 2 thin chunk sizes if thin pool driver supports that.
Allow limited metadata changes when PVs are missing via [vg|lv]change.
diff --git a/configure b/configure
index 13fb6d6..add489a 100755
--- a/configure
+++ b/configure
@@ -624,6 +624,9 @@ SELINUX_LIBS
REPLICATORS
READLINE_LIBS
RAID
+PYTHON_LIBDIRS
+PYTHON_INCDIRS
+PYTHON_BINDINGS
PTHREAD_LIBS
POOL
PKGCONFIG
@@ -686,10 +689,15 @@ BUILD_CMIRRORD
APPLIB
MODPROBE_CMD
MSGFMT
+PYTHON_CONFIG
+PYTHON
LVM2CMD_LIB
LVM2APP_LIB
UDEV_LIBS
UDEV_CFLAGS
+VALGRIND_POOL
+VALGRIND_LIBS
+VALGRIND_CFLAGS
CUNIT_LIBS
CUNIT_CFLAGS
GENPNG
@@ -842,6 +850,7 @@ enable_ioctl
enable_o_direct
enable_applib
enable_cmdlib
+enable_python_bindings
enable_pkgconfig
enable_write_install
enable_fsadm
@@ -901,6 +910,8 @@ SACKPT_CFLAGS
SACKPT_LIBS
CUNIT_CFLAGS
CUNIT_LIBS
+VALGRIND_CFLAGS
+VALGRIND_LIBS
UDEV_CFLAGS
UDEV_LIBS'
@@ -1542,6 +1553,8 @@ Optional Features:
--disable-o_direct disable O_DIRECT
--enable-applib build application library
--enable-cmdlib build shared command library
+ --enable-python_bindings
+ build Python applib bindings
--enable-pkgconfig install pkgconfig support
--enable-write_install install user writable files
--disable-fsadm disable fsadm
@@ -1678,6 +1691,10 @@ Some influential environment variables:
CUNIT_CFLAGS
C compiler flags for CUNIT, overriding pkg-config
CUNIT_LIBS linker flags for CUNIT, overriding pkg-config
+ VALGRIND_CFLAGS
+ C compiler flags for VALGRIND, overriding pkg-config
+ VALGRIND_LIBS
+ linker flags for VALGRIND, overriding pkg-config
UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config
UDEV_LIBS linker flags for UDEV, overriding pkg-config
@@ -8814,23 +8831,80 @@ fi
$as_echo "$VALGRIND_POOL" >&6; }
if test "$VALGRIND_POOL" = yes; then
- for ac_header in valgrind/memcheck.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "valgrind/memcheck.h" "ac_cv_header_valgrind_memcheck_h" "$ac_includes_default"
-if test "x$ac_cv_header_valgrind_memcheck_h" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_VALGRIND_MEMCHECK_H 1
-_ACEOF
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND" >&5
+$as_echo_n "checking for VALGRIND... " >&6; }
+
+if test -n "$VALGRIND_CFLAGS"; then
+ pkg_cv_VALGRIND_CFLAGS="$VALGRIND_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"valgrind\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "valgrind") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_VALGRIND_CFLAGS=`$PKG_CONFIG --cflags "valgrind" 2>/dev/null`
else
- as_fn_error $? "bailing out" "$LINENO" 5
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$VALGRIND_LIBS"; then
+ pkg_cv_VALGRIND_LIBS="$VALGRIND_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"valgrind\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "valgrind") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_VALGRIND_LIBS=`$PKG_CONFIG --libs "valgrind" 2>/dev/null`
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
fi
-done
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ VALGRIND_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "valgrind" 2>&1`
+ else
+ VALGRIND_PKG_ERRORS=`$PKG_CONFIG --print-errors "valgrind" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$VALGRIND_PKG_ERRORS" >&5
+
+ as_fn_error $? "bailing out" "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "bailing out" "$LINENO" 5
+else
+ VALGRIND_CFLAGS=$pkg_cv_VALGRIND_CFLAGS
+ VALGRIND_LIBS=$pkg_cv_VALGRIND_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
$as_echo "#define VALGRIND_POOL 1" >>confdefs.h
+
+
fi
################################################################################
@@ -9121,6 +9195,122 @@ test x$CMDLIB = xyes \
|| LVM2CMD_LIB=
################################################################################
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Python wrapper for liblvm2app.so" >&5
+$as_echo_n "checking whether to build Python wrapper for liblvm2app.so... " >&6; }
+# Check whether --enable-python_bindings was given.
+if test "${enable_python_bindings+set}" = set; then :
+ enableval=$enable_python_bindings; PYTHON_BINDINGS=$enableval
+else
+ PYTHON_BINDINGS=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_BINDINGS" >&5
+$as_echo "$PYTHON_BINDINGS" >&6; }
+
+if test x$PYTHON_BINDINGS = xyes; then
+ if test x$APPLIB != xyes; then
+ as_fn_error $? "--enable-python_bindings requires --enable-applib
+ " "$LINENO" 5
+ fi
+
+ # Extract the first word of "python", so it can be a program name with args.
+set dummy python; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PYTHON+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PYTHON in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_PYTHON" && ac_cv_path_PYTHON="notfound"
+ ;;
+esac
+fi
+PYTHON=$ac_cv_path_PYTHON
+if test -n "$PYTHON"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test x$PYTHON == xnotfound; then
+ as_fn_error $? "python is required for --enable-python_bindings but cannot be found
+ " "$LINENO" 5
+ fi
+
+ # Extract the first word of "python-config", so it can be a program name with args.
+set dummy python-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PYTHON_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PYTHON_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PYTHON_CONFIG="$PYTHON_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_PYTHON_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_PYTHON_CONFIG" && ac_cv_path_PYTHON_CONFIG="notfound"
+ ;;
+esac
+fi
+PYTHON_CONFIG=$ac_cv_path_PYTHON_CONFIG
+if test -n "$PYTHON_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CONFIG" >&5
+$as_echo "$PYTHON_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test x$PYTHON_CONFIG == xnotfound; then
+ as_fn_error $? "python headers are required for --enable-python_bindings but cannot be found
+ " "$LINENO" 5
+ fi
+
+ PYTHON_INCDIRS=`$PYTHON_CONFIG --includes`
+ PYTHON_LIBDIRS=`$PYTHON_CONFIG --libs`
+
+fi
+
+################################################################################
# Check whether --enable-pkgconfig was given.
if test "${enable_pkgconfig+set}" = set; then :
enableval=$enable_pkgconfig; PKGCONFIG=$enableval
@@ -10576,8 +10766,12 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
+
+
+
+
################################################################################
-ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile doc/Makefile doc/example.conf include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_l
vmetad_systemd_red_hat.socket scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/dm_event_systemd_red_hat.socket scripts/dm_event_systemd_red_hat.service scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
+ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile doc/Makefile doc/example.conf include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/lvm2_lvm
etad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/dm_event_systemd_red_hat.socket scripts/dm_event_systemd_red_hat.service scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -11303,6 +11497,8 @@ do
"liblvm/liblvm2app.pc") CONFIG_FILES="$CONFIG_FILES liblvm/liblvm2app.pc" ;;
"man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
"po/Makefile") CONFIG_FILES="$CONFIG_FILES po/Makefile" ;;
+ "python/Makefile") CONFIG_FILES="$CONFIG_FILES python/Makefile" ;;
+ "python/setup.py") CONFIG_FILES="$CONFIG_FILES python/setup.py" ;;
"scripts/clvmd_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/clvmd_init_red_hat" ;;
"scripts/cmirrord_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/cmirrord_init_red_hat" ;;
"scripts/lvm2_lvmetad_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_init_red_hat" ;;
diff --git a/configure.in b/configure.in
index 16f91fb..eb20908 100644
--- a/configure.in
+++ b/configure.in
@@ -1027,6 +1027,40 @@ test x$CMDLIB = xyes \
|| LVM2CMD_LIB=
################################################################################
+dnl -- Enable Python liblvm2app bindings
+AC_MSG_CHECKING(whether to build Python wrapper for liblvm2app.so)
+AC_ARG_ENABLE(python_bindings,
+ AC_HELP_STRING([--enable-python_bindings], [build Python applib bindings]),
+ PYTHON_BINDINGS=$enableval, PYTHON_BINDINGS=no)
+AC_MSG_RESULT($PYTHON_BINDINGS)
+
+if test x$PYTHON_BINDINGS = xyes; then
+ if test x$APPLIB != xyes; then
+ AC_MSG_ERROR(
+ --enable-python_bindings requires --enable-applib
+ )
+ fi
+
+ AC_PATH_PROG(PYTHON, python, notfound)
+ if test x$PYTHON == xnotfound; then
+ AC_MSG_ERROR(
+[python is required for --enable-python_bindings but cannot be found]
+ )
+ fi
+
+ AC_PATH_PROG(PYTHON_CONFIG, python-config, notfound)
+ if test x$PYTHON_CONFIG == xnotfound; then
+ AC_MSG_ERROR(
+[python headers are required for --enable-python_bindings but cannot be found]
+ )
+ fi
+
+ PYTHON_INCDIRS=`$PYTHON_CONFIG --includes`
+ PYTHON_LIBDIRS=`$PYTHON_CONFIG --libs`
+
+fi
+
+################################################################################
dnl -- Enable pkg-config
AC_ARG_ENABLE(pkgconfig,
AC_HELP_STRING([--enable-pkgconfig], [install pkgconfig support]),
@@ -1523,6 +1557,10 @@ AC_SUBST(OCFDIR)
AC_SUBST(PKGCONFIG)
AC_SUBST(POOL)
AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PYTHON)
+AC_SUBST(PYTHON_BINDINGS)
+AC_SUBST(PYTHON_INCDIRS)
+AC_SUBST(PYTHON_LIBDIRS)
AC_SUBST(QUORUM_CFLAGS)
AC_SUBST(QUORUM_LIBS)
AC_SUBST(RAID)
@@ -1605,6 +1643,8 @@ liblvm/Makefile
liblvm/liblvm2app.pc
man/Makefile
po/Makefile
+python/Makefile
+python/setup.py
scripts/clvmd_init_red_hat
scripts/cmirrord_init_red_hat
scripts/lvm2_lvmetad_init_red_hat
diff --git a/lib/misc/configure.h.in b/lib/misc/configure.h.in
index c1d1218..fdc5a26 100644
--- a/lib/misc/configure.h.in
+++ b/lib/misc/configure.h.in
@@ -432,9 +432,6 @@
/* Define to 1 if you have the <utmpx.h> header file. */
#undef HAVE_UTMPX_H
-/* Define to 1 if you have the <valgrind/memcheck.h> header file. */
-#undef HAVE_VALGRIND_MEMCHECK_H
-
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
diff --git a/make.tmpl.in b/make.tmpl.in
index 21fd415..8b56f01 100644
--- a/make.tmpl.in
+++ b/make.tmpl.in
@@ -28,6 +28,7 @@ LN_S = @LN_S@
SED = @SED@
CFLOW_CMD = @CFLOW_CMD@
AWK = @AWK@
+PYTHON = @PYTHON@
LIBS = @LIBS@
# Extra libraries always linked with static binaries
@@ -52,6 +53,7 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
udev_prefix = @udev_prefix@
sysconfdir = @sysconfdir@
+rootdir = $(DESTDIR)/
bindir = $(DESTDIR)@bindir@
confdir = $(DESTDIR)@CONFDIR@/lvm
includedir = $(DESTDIR)@includedir@
@@ -196,6 +198,7 @@ POTFILES = $(SOURCES:%.c=%.pot)
.PHONY: install install_cluster install_device-mapper install_lvm2
.PHONY: install_lib_shared install_dm_plugin install_lvm2_plugin
.PHONY: install_ocf help
+.PHONY: python_bindings install_python_bindings
.PHONY: $(SUBDIRS) $(SUBDIRS.install) $(SUBDIRS.clean) $(SUBDIRS.distclean)
.PHONY: $(SUBDIRS.pofile) $(SUBDIRS.install_cluster) $(SUBDIRS.cflow)
.PHONY: $(SUBDIRS.device-mapper) $(SUBDIRS.install-device-mapper)
diff --git a/python/Makefile.in b/python/Makefile.in
new file mode 100644
index 0000000..1fead22
--- /dev/null
+++ b/python/Makefile.in
@@ -0,0 +1,39 @@
+#
+# Copyright (C) 2011-2012 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+
+python_bindings: .liblvm_built
+
+.liblvm_built: liblvm_python.c
+ $(PYTHON) setup.py build
+ touch $@
+
+liblvm_python.c:
+ $(LN_S) $(srcdir)/liblvm.c $@
+
+include $(top_builddir)/make.tmpl
+
+install_python_bindings: python_bindings
+ $(PYTHON) setup.py install --skip-build --root $(rootdir)
+
+install_lvm2: install_python_bindings
+
+install: install_lvm2
+
+CLEAN_TARGETS += .liblvm_built liblvm_python.c
+
+DISTCLEAN_DIRS += build
+DISTCLEAN_TARGETS += setup.py
diff --git a/python/example.py b/python/example.py
new file mode 100644
index 0000000..67bb7e4
--- /dev/null
+++ b/python/example.py
@@ -0,0 +1,125 @@
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM2.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#-----------------------------
+# Python example code:
+#-----------------------------
+
+import lvm
+
+# Note: This example will create a logical unit, tag it and
+# delete it, don't run this on production box!
+
+#Dump information about PV
+def print_pv(pv):
+ print 'PV name: ', pv.getName(), ' ID: ', pv.getUuid(), 'Size: ', pv.getSize()
+
+
+#Dump some information about a specific volume group
+def print_vg(h, vg_name):
+ #Open read only
+ vg = h.vgOpen(vg_name, 'r')
+
+ print 'Volume group:', vg_name, 'Size: ', vg.getSize()
+
+ #Retrieve a list of Physical volumes for this volume group
+ pv_list = vg.listPVs()
+
+ #Print out the physical volumes
+ for p in pv_list:
+ print_pv(p)
+
+ #Get a list of logical volumes in this volume group
+ lv_list = vg.listLVs()
+ if len(lv_list):
+ for l in lv_list:
+ print 'LV name: ', l.getName(), ' ID: ', l.getUuid()
+ else:
+ print 'No logical volumes present!'
+
+ vg.close()
+
+#Returns the name of a vg with space available
+def find_vg_with_free_space(h):
+ free_space = 0
+ rc = None
+
+ vg_names = l.listVgNames()
+ for v in vg_names:
+ vg = h.vgOpen(v, 'r')
+ c_free = vg.getFreeSize()
+ if c_free > free_space:
+ free_space = c_free
+ rc = v
+ vg.close()
+
+ return rc
+
+#Walk through the volume groups and fine one with space in which we can
+#create a new logical volume
+def create_delete_logical_volume(h):
+ vg_name = find_vg_with_free_space(h)
+
+ print 'Using volume group ', vg_name, ' for example'
+
+ if vg_name:
+ vg = h.vgOpen(vg_name, 'w')
+ lv = vg.createLvLinear('python_lvm_ok_to_delete', vg.getFreeSize())
+
+ if lv:
+ print 'New lv, id= ', lv.getUuid()
+
+ #Create a tag
+ lv.addTag('Demo_tag')
+
+ #Get the tags
+ tags = lv.getTags()
+ for t in tags:
+ #Remove tag
+ lv.removeTag(t)
+
+ #Try to rename
+ lv.rename("python_lvm_ok_to_be_removed_shortly")
+ print 'LV name= ', lv.getName()
+
+ lv.deactivate()
+ lv.remove()
+
+ vg.close()
+ else:
+ print 'No free space available to create demo lv!'
+
+if __name__ == '__main__':
+ #Create a new LVM instance
+ l = lvm.Liblvm()
+
+ #What version
+ print 'lvm version=', l.getVersion()
+
+ #Get a list of volume group names
+ vg_names = l.listVgNames()
+
+ #For each volume group display some information about each of them
+ for vg_i in vg_names:
+ print_vg(l, vg_i)
+
+ #Demo creating a logical volume
+ create_delete_logical_volume(l)
+
+ #Close
+ l.close()
diff --git a/python/liblvm.c b/python/liblvm.c
new file mode 100644
index 0000000..cbfa170
--- /dev/null
+++ b/python/liblvm.c
@@ -0,0 +1,1711 @@
+/*
+ * Liblvm -- Python interface to LVM2 API.
+ *
+ * Copyright (C) 2010, 2012 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Lars Sjostrom (lars sjostrom redhat com)
+ * Andy Grover (agrover redhat com)
+ * Tony Asleson (tasleson redhat com)
+ */
+
+#include <Python.h>
+#include "lvm2app.h"
+
+typedef struct {
+ PyObject_HEAD
+ lvm_t libh; /* lvm lib handle */
+} lvmobject;
+
+typedef struct {
+ PyObject_HEAD
+ vg_t vg; /* vg handle */
+ lvmobject *lvm_obj;
+} vgobject;
+
+typedef struct {
+ PyObject_HEAD
+ lv_t lv; /* lv handle */
+ lvmobject *lvm_obj;
+} lvobject;
+
+typedef struct {
+ PyObject_HEAD
+ pv_t pv; /* pv handle */
+ lvmobject *lvm_obj;
+} pvobject;
+
+typedef struct {
+ PyObject_HEAD
+ lvseg_t lv_seg; /* lv segment handle */
+ lvmobject *lvm_obj;
+} lvsegobject;
+
+typedef struct {
+ PyObject_HEAD
+ pvseg_t pv_seg; /* pv segment handle */
+ lvmobject *lvm_obj;
+} pvsegobject;
+
+static PyTypeObject LibLVMvgType;
+static PyTypeObject LibLVMlvType;
+static PyTypeObject LibLVMpvType;
+static PyTypeObject LibLVMlvsegType;
+static PyTypeObject LibLVMpvsegType;
+
+static PyObject *LibLVMError;
+
+
+/* ----------------------------------------------------------------------
+ * LVM object initialization/deallocation
+ */
+
+static int
+liblvm_init(lvmobject *self, PyObject *arg)
+{
+ char *systemdir = NULL;
+
+ if (!PyArg_ParseTuple(arg, "|s", &systemdir))
+ return -1;
+
+ self->libh = lvm_init(systemdir);
+ if (lvm_errno(self->libh)) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+liblvm_dealloc(lvmobject *self)
+{
+ /* if already closed, don't reclose it */
+ if (self->libh != NULL){
+ lvm_quit(self->libh);
+ }
+
+ PyObject_Del(self);
+}
+
+#define LVM_VALID(lvmobject) \
+ do { \
+ if (!lvmobject->libh) { \
+ PyErr_SetString(PyExc_UnboundLocalError, "LVM object invalid"); \
+ return NULL; \
+ } \
+ } while (0)
+
+static PyObject *
+liblvm_get_last_error(lvmobject *self)
+{
+ PyObject *info;
+
+ LVM_VALID(self);
+
+ if((info = PyTuple_New(2)) == NULL)
+ return NULL;
+
+ PyTuple_SetItem(info, 0, PyInt_FromLong((long) lvm_errno(self->libh)));
+ PyTuple_SetItem(info, 1, PyString_FromString(lvm_errmsg(self->libh)));
+
+ return info;
+}
+
+static PyObject *
+liblvm_library_get_version(lvmobject *self)
+{
+ LVM_VALID(self);
+
+ return Py_BuildValue("s", lvm_library_get_version());
+}
+
+
+static PyObject *
+liblvm_close(lvmobject *self)
+{
+ LVM_VALID(self);
+
+ /* if already closed, don't reclose it */
+ if (self->libh != NULL)
+ lvm_quit(self->libh);
+
+ self->libh = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_list_vg_names(lvmobject *self)
+{
+ struct dm_list *vgnames;
+ struct lvm_str_list *strl;
+ PyObject * pytuple;
+ int i = 0;
+
+ LVM_VALID(self);
+
+ vgnames = lvm_list_vg_names(self->libh);
+ if (!vgnames) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self));
+ return NULL;
+ }
+
+ pytuple = PyTuple_New(dm_list_size(vgnames));
+ if (!pytuple)
+ return NULL;
+
+ dm_list_iterate_items(strl, vgnames) {
+ PyTuple_SET_ITEM(pytuple, i, PyString_FromString(strl->str));
+ i++;
+ }
+
+ return pytuple;
+}
+
+static PyObject *
+liblvm_lvm_list_vg_uuids(lvmobject *self)
+{
+ struct dm_list *uuids;
+ struct lvm_str_list *strl;
+ PyObject * pytuple;
+ int i = 0;
+
+ LVM_VALID(self);
+
+ uuids = lvm_list_vg_uuids(self->libh);
+ if (!uuids) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self));
+ return NULL;
+ }
+
+ pytuple = PyTuple_New(dm_list_size(uuids));
+ if (!pytuple)
+ return NULL;
+
+ dm_list_iterate_items(strl, uuids) {
+ PyTuple_SET_ITEM(pytuple, i, PyString_FromString(strl->str));
+ i++;
+ }
+
+ return pytuple;
+}
+
+static PyObject *
+liblvm_lvm_percent_to_float(lvmobject *self, PyObject *arg)
+{
+ double converted;
+ int percent;
+
+ LVM_VALID(self);
+
+ if (!PyArg_ParseTuple(arg, "i", &percent))
+ return NULL;
+
+ converted = lvm_percent_to_float(percent);
+ return Py_BuildValue("d", converted);
+}
+
+static PyObject *
+liblvm_lvm_vgname_from_pvid(lvmobject *self, PyObject *arg)
+{
+ const char *pvid;
+ const char *vgname;
+
+ LVM_VALID(self);
+
+ if (!PyArg_ParseTuple(arg, "s", &pvid))
+ return NULL;
+
+ if((vgname = lvm_vgname_from_pvid(self->libh, pvid)) == NULL) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self));
+ return NULL;
+ }
+
+ return Py_BuildValue("s", vgname);
+}
+
+static PyObject *
+liblvm_lvm_vgname_from_device(lvmobject *self, PyObject *arg)
+{
+ const char *device;
+ const char *vgname;
+
+ LVM_VALID(self);
+
+ if (!PyArg_ParseTuple(arg, "s", &device))
+ return NULL;
+
+ if((vgname = lvm_vgname_from_device(self->libh, device)) == NULL) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self));
+ return NULL;
+ }
+
+ return Py_BuildValue("s", vgname);
+}
+
+
+static PyObject *
+liblvm_lvm_config_find_bool(lvmobject *self, PyObject *arg)
+{
+ const char *config;
+ int rval;
+ PyObject *rc;
+
+ LVM_VALID(self);
+
+ if (!PyArg_ParseTuple(arg, "s", &config))
+ return NULL;
+
+ if ((rval = lvm_config_find_bool(self->libh, config, -10)) == -10) {
+ /* Retrieving error information yields no error in this case */
+ PyErr_Format(PyExc_ValueError, "config path not found");
+ return NULL;
+ }
+
+ rc = (rval) ? Py_True: Py_False;
+
+ Py_INCREF(rc);
+ return rc;
+}
+
+static PyObject *
+liblvm_lvm_config_reload(lvmobject *self)
+{
+ int rval;
+
+ LVM_VALID(self);
+
+ if((rval = lvm_config_reload(self->libh)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+static PyObject *
+liblvm_lvm_scan(lvmobject *self)
+{
+ int rval;
+
+ LVM_VALID(self);
+
+ if((rval = lvm_scan(self->libh)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_config_override(lvmobject *self, PyObject *arg)
+{
+ const char *config;
+ int rval;
+
+ LVM_VALID(self);
+
+ if (!PyArg_ParseTuple(arg, "s", &config))
+ return NULL;
+
+ if ((rval = lvm_config_override(self->libh, config)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+/* ----------------------------------------------------------------------
+ * VG object initialization/deallocation
+ */
+
+
+static PyObject *
+liblvm_lvm_vg_open(lvmobject *lvm, PyObject *args)
+{
+ const char *vgname;
+ const char *mode = NULL;
+
+ vgobject *self;
+
+ LVM_VALID(lvm);
+
+ if (!PyArg_ParseTuple(args, "s|s", &vgname, &mode)) {
+ return NULL;
+ }
+
+ if (mode == NULL)
+ mode = "r";
+
+ if ((self = PyObject_New(vgobject, &LibLVMvgType)) == NULL)
+ return NULL;
+
+ if ((self->vg = lvm_vg_open(lvm->libh, vgname, mode, 0))== NULL) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(lvm));
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->lvm_obj = lvm;
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+liblvm_lvm_vg_create(lvmobject *lvm, PyObject *args)
+{
+ const char *vgname;
+ vgobject *self;
+
+ LVM_VALID(lvm);
+
+ if (!PyArg_ParseTuple(args, "s", &vgname)) {
+ return NULL;
+ }
+
+ if ((self = PyObject_New(vgobject, &LibLVMvgType)) == NULL)
+ return NULL;
+
+ if ((self->vg = lvm_vg_create(lvm->libh, vgname))== NULL) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(lvm));
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->lvm_obj = lvm;
+
+ return (PyObject *)self;
+}
+
+static void
+liblvm_vg_dealloc(vgobject *self)
+{
+ /* if already closed, don't reclose it */
+ if (self->vg != NULL)
+ lvm_vg_close(self->vg);
+ PyObject_Del(self);
+}
+
+/* VG Methods */
+
+#define VG_VALID(vgobject) \
+ do { \
+ if (!vgobject->vg) { \
+ PyErr_SetString(PyExc_UnboundLocalError, "VG object invalid"); \
+ return NULL; \
+ } \
+ } while (0)
+
+static PyObject *
+liblvm_lvm_vg_close(vgobject *self)
+{
+ /* if already closed, don't reclose it */
+ if (self->vg != NULL)
+ lvm_vg_close(self->vg);
+
+ self->vg = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_vg_get_name(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("s", lvm_vg_get_name(self->vg));
+}
+
+
+static PyObject *
+liblvm_lvm_vg_get_uuid(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("s", lvm_vg_get_uuid(self->vg));
+}
+
+static PyObject *
+liblvm_lvm_vg_remove(vgobject *self)
+{
+ int rval;
+
+ VG_VALID(self);
+
+ if ((rval = lvm_vg_remove(self->vg)) == -1)
+ goto error;
+
+ if (lvm_vg_write(self->vg) == -1)
+ goto error;
+
+ self->vg = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+error:
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+}
+
+static PyObject *
+liblvm_lvm_vg_extend(vgobject *self, PyObject *args)
+{
+ const char *device;
+ int rval;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &device)) {
+ return NULL;
+ }
+
+ if ((rval = lvm_vg_extend(self->vg, device)) == -1)
+ goto error;
+
+ if (lvm_vg_write(self->vg) == -1)
+ goto error;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+error:
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+}
+
+static PyObject *
+liblvm_lvm_vg_reduce(vgobject *self, PyObject *args)
+{
+ const char *device;
+ int rval;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &device)) {
+ return NULL;
+ }
+
+ if ((rval = lvm_vg_reduce(self->vg, device)) == -1)
+ goto error;
+
+ if (lvm_vg_write(self->vg) == -1)
+ goto error;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+error:
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+}
+
+static PyObject *
+liblvm_lvm_vg_add_tag(vgobject *self, PyObject *args)
+{
+ const char *tag;
+ int rval;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &tag)) {
+ return NULL;
+ }
+ if ((rval = lvm_vg_add_tag(self->vg, tag)) == -1)
+ goto error;
+
+ if (lvm_vg_write(self->vg) == -1)
+ goto error;
+
+ return Py_BuildValue("i", rval);
+
+error:
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+}
+
+static PyObject *
+liblvm_lvm_vg_remove_tag(vgobject *self, PyObject *args)
+{
+ const char *tag;
+ int rval;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &tag)) {
+ return NULL;
+ }
+
+ if ((rval = lvm_vg_remove_tag(self->vg, tag)) == -1)
+ goto error;
+
+ if (lvm_vg_write(self->vg) == -1)
+ goto error;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+error:
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+
+}
+
+static PyObject *
+liblvm_lvm_vg_is_clustered(vgobject *self)
+{
+ PyObject *rval;
+
+ VG_VALID(self);
+
+ rval = ( lvm_vg_is_clustered(self->vg) == 1) ? Py_True : Py_False;
+
+ Py_INCREF(rval);
+ return rval;
+}
+
+static PyObject *
+liblvm_lvm_vg_is_exported(vgobject *self)
+{
+ PyObject *rval;
+
+ VG_VALID(self);
+
+ rval = ( lvm_vg_is_exported(self->vg) == 1) ? Py_True : Py_False;
+
+ Py_INCREF(rval);
+ return rval;
+}
+
+static PyObject *
+liblvm_lvm_vg_is_partial(vgobject *self)
+{
+ PyObject *rval;
+
+ VG_VALID(self);
+
+ rval = ( lvm_vg_is_partial(self->vg) == 1) ? Py_True : Py_False;
+
+ Py_INCREF(rval);
+ return rval;
+}
+
+static PyObject *
+liblvm_lvm_vg_get_seqno(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("l", lvm_vg_get_seqno(self->vg));
+}
+
+static PyObject *
+liblvm_lvm_vg_get_size(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("l", lvm_vg_get_size(self->vg));
+}
+
+static PyObject *
+liblvm_lvm_vg_get_free_size(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("l", lvm_vg_get_free_size(self->vg));
+}
+
+static PyObject *
+liblvm_lvm_vg_get_extent_size(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("l", lvm_vg_get_extent_size(self->vg));
+}
+
+static PyObject *
+liblvm_lvm_vg_get_extent_count(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("l", lvm_vg_get_extent_count(self->vg));
+}
+
+static PyObject *
+liblvm_lvm_vg_get_free_extent_count(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("l", lvm_vg_get_free_extent_count(self->vg));
+}
+
+/* Builds a python tuple ([string|number], bool) from a struct lvm_property_value */
+static PyObject *
+get_property(lvmobject *h, struct lvm_property_value *prop)
+{
+ PyObject *pytuple;
+ PyObject *setable;
+
+ if( !prop->is_valid ) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(h));
+ return NULL;
+ }
+
+ pytuple = PyTuple_New(2);
+ if (!pytuple)
+ return NULL;
+
+ if( prop->is_integer ) {
+ PyTuple_SET_ITEM(pytuple, 0, Py_BuildValue("K", prop->value.integer));
+ } else {
+ PyTuple_SET_ITEM(pytuple, 0, PyString_FromString(prop->value.string));
+ }
+
+ if (prop->is_settable) {
+ setable = Py_True;
+ } else {
+ setable = Py_False;
+ }
+
+ Py_INCREF(setable);
+ PyTuple_SET_ITEM(pytuple, 1, setable);
+ return pytuple;
+}
+
+/* This will return a tuple of (value, bool) with the value being a string or
+ integer and bool indicating if property is settable */
+static PyObject *
+liblvm_lvm_vg_get_property(vgobject *self, PyObject *args)
+{
+ const char *name;
+ struct lvm_property_value prop_value;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ prop_value = lvm_vg_get_property(self->vg, name);
+ return get_property(self->lvm_obj, &prop_value);
+}
+
+static PyObject *
+liblvm_lvm_vg_set_property(vgobject *self, PyObject *args)
+{
+ const char *property_name = NULL;
+ PyObject *variant_type_arg = NULL;
+ struct lvm_property_value lvm_property;
+ char *string_value = NULL;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "sO", &property_name, &variant_type_arg))
+ return NULL;
+
+ lvm_property = lvm_vg_get_property(self->vg, property_name);
+
+ if( !lvm_property.is_valid ) {
+ goto lvmerror;
+ }
+
+ if(PyObject_IsInstance(variant_type_arg, (PyObject*)&PyString_Type)) {
+
+ if (!lvm_property.is_string) {
+ PyErr_Format(PyExc_ValueError, "Property requires string value");
+ goto bail;
+ }
+
+ /* Based on cursory code inspection this path may cause a memory
+ leak when calling into set_property, need to verify*/
+ string_value = strdup(PyString_AsString(variant_type_arg));
+ lvm_property.value.string = string_value;
+ if(!lvm_property.value.string) {
+ PyErr_NoMemory();
+ goto bail;
+ }
+
+ } else {
+
+ if (!lvm_property.is_integer) {
+ PyErr_Format(PyExc_ValueError, "Property requires numeric value");
+ goto bail;
+ }
+
+ if(PyObject_IsInstance(variant_type_arg, (PyObject*)&PyInt_Type)) {
+ int temp_py_int = PyInt_AsLong(variant_type_arg);
+
+ /* -1 could be valid, need to see if an exception was gen. */
+ if( -1 == temp_py_int ) {
+ if( PyErr_Occurred() ) {
+ goto bail;
+ }
+ }
+
+ if (temp_py_int < 0) {
+ PyErr_Format(PyExc_ValueError, "Positive integers only!");
+ goto bail;
+ }
+
+ lvm_property.value.integer = temp_py_int;
+ } else if(PyObject_IsInstance(variant_type_arg, (PyObject*)&PyLong_Type)){
+ /* This will fail on negative numbers */
+ unsigned long long temp_py_long = PyLong_AsUnsignedLongLong(variant_type_arg);
+ if( (unsigned long long)-1 == temp_py_long ) {
+ goto bail;
+ }
+
+ lvm_property.value.integer = temp_py_long;
+ } else {
+ PyErr_Format(PyExc_ValueError, "supported value types are numeric and string");
+ goto bail;
+ }
+ }
+
+ if( -1 == lvm_vg_set_property(self->vg, property_name, &lvm_property) ) {
+ goto lvmerror;
+ }
+
+ if( -1 == lvm_vg_write(self->vg)) {
+ goto lvmerror;
+ }
+
+ Py_DECREF(variant_type_arg);
+ Py_INCREF(Py_None);
+ return Py_None;
+
+lvmerror:
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+bail:
+ free(string_value);
+ if( variant_type_arg ) {
+ Py_DECREF(variant_type_arg);
+ variant_type_arg = NULL;
+ }
+ return NULL;
+}
+
+static PyObject *
+liblvm_lvm_vg_get_pv_count(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("l", lvm_vg_get_pv_count(self->vg));
+}
+
+static PyObject *
+liblvm_lvm_vg_get_max_pv(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("l", lvm_vg_get_max_pv(self->vg));
+}
+
+static PyObject *
+liblvm_lvm_vg_get_max_lv(vgobject *self)
+{
+ VG_VALID(self);
+
+ return Py_BuildValue("l", lvm_vg_get_max_lv(self->vg));
+}
+
+static PyObject *
+liblvm_lvm_vg_set_extent_size(vgobject *self, PyObject *args)
+{
+ uint32_t new_size;
+ int rval;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "l", &new_size)) {
+ return NULL;
+ }
+
+ if ((rval = lvm_vg_set_extent_size(self->vg, new_size)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_vg_list_lvs(vgobject *vg)
+{
+ struct dm_list *lvs;
+ struct lvm_lv_list *lvl;
+ PyObject * pytuple;
+ lvobject * self;
+ int i = 0;
+
+ VG_VALID(vg);
+
+ /* unlike other LVM api calls, if there are no results, we get NULL */
+ lvs = lvm_vg_list_lvs(vg->vg);
+ if (!lvs)
+ return Py_BuildValue("()");
+
+ pytuple = PyTuple_New(dm_list_size(lvs));
+ if (!pytuple)
+ return NULL;
+
+ dm_list_iterate_items(lvl, lvs) {
+ /* Create and initialize the object */
+ self = PyObject_New(lvobject, &LibLVMlvType);
+ if (!self) {
+ Py_DECREF(pytuple);
+ return NULL;
+ }
+
+ self->lv = lvl->lv;
+ self->lvm_obj = vg->lvm_obj;
+ PyTuple_SET_ITEM(pytuple, i, (PyObject *) self);
+ i++;
+ }
+
+ return pytuple;
+}
+
+static PyObject *
+liblvm_lvm_vg_get_tags(vgobject *self)
+{
+ struct dm_list *tags;
+ struct lvm_str_list *strl;
+ PyObject * pytuple;
+ int i = 0;
+
+ VG_VALID(self);
+
+ tags = lvm_vg_get_tags(self->vg);
+ if (!tags) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ pytuple = PyTuple_New(dm_list_size(tags));
+ if (!pytuple)
+ return NULL;
+
+ dm_list_iterate_items(strl, tags) {
+ PyTuple_SET_ITEM(pytuple, i, PyString_FromString(strl->str));
+ i++;
+ }
+
+ return pytuple;
+}
+
+static PyObject *
+liblvm_lvm_vg_create_lv_linear(vgobject *vg, PyObject *args)
+{
+ const char *vgname;
+ uint64_t size;
+ lvobject *self;
+
+ VG_VALID(vg);
+
+ if (!PyArg_ParseTuple(args, "sl", &vgname, &size)) {
+ return NULL;
+ }
+
+ if ((self = PyObject_New(lvobject, &LibLVMlvType)) == NULL)
+ return NULL;
+
+ if ((self->lv = lvm_vg_create_lv_linear(vg->vg, vgname, size))== NULL) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(vg->lvm_obj));
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->lvm_obj = vg->lvm_obj;
+
+ return (PyObject *)self;
+}
+
+static void
+liblvm_lv_dealloc(lvobject *self)
+{
+ PyObject_Del(self);
+}
+
+static PyObject *
+liblvm_lvm_vg_list_pvs(vgobject *vg)
+{
+ struct dm_list *pvs;
+ struct lvm_pv_list *pvl;
+ PyObject * pytuple;
+ pvobject * self;
+ int i = 0;
+
+ VG_VALID(vg);
+
+ /* unlike other LVM api calls, if there are no results, we get NULL */
+ pvs = lvm_vg_list_pvs(vg->vg);
+ if (!pvs)
+ return Py_BuildValue("()");
+
+ pytuple = PyTuple_New(dm_list_size(pvs));
+ if (!pytuple)
+ return NULL;
+
+ dm_list_iterate_items(pvl, pvs) {
+ /* Create and initialize the object */
+ self = PyObject_New(pvobject, &LibLVMpvType);
+ if (!self) {
+ Py_DECREF(pytuple);
+ return NULL;
+ }
+
+ self->pv = pvl->pv;
+ self->lvm_obj = vg->lvm_obj;
+ PyTuple_SET_ITEM(pytuple, i, (PyObject *) self);
+ i++;
+ }
+
+ return pytuple;
+}
+
+typedef lv_t (*lv_fetch_by_N)(vg_t vg, const char *id);
+typedef pv_t (*pv_fetch_by_N)(vg_t vg, const char *id);
+
+static PyObject *
+liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method)
+{
+ const char *id;
+ lvobject *rc;
+ lv_t lv = NULL;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(arg, "s", &id))
+ return NULL;
+
+ lv = method(self->vg, id);
+ if( !lv ) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ rc = PyObject_New(lvobject, &LibLVMlvType);
+ if( !rc ) {
+ return NULL;
+ }
+
+ rc->lv = lv;
+ rc->lvm_obj = self->lvm_obj;
+ return (PyObject *)rc;
+}
+
+static PyObject *
+liblvm_lvm_lv_from_name(vgobject *self, PyObject *arg)
+{
+ return liblvm_lvm_lv_from_N(self, arg, lvm_lv_from_name);
+}
+
+static PyObject *
+liblvm_lvm_lv_from_uuid(vgobject *self, PyObject *arg)
+{
+ return liblvm_lvm_lv_from_N(self, arg, lvm_lv_from_uuid);
+}
+
+static PyObject *
+liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method)
+{
+ const char *id;
+ pvobject *rc;
+ pv_t pv = NULL;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(arg, "s", &id))
+ return NULL;
+
+ pv = method(self->vg, id);
+ if( !pv ) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ rc = PyObject_New(pvobject, &LibLVMpvType);
+ if( !rc ) {
+ return NULL;
+ }
+
+ rc->pv = pv;
+ rc->lvm_obj = self->lvm_obj;
+ return (PyObject *)rc;
+}
+
+static PyObject *
+liblvm_lvm_pv_from_name(vgobject *self, PyObject *arg)
+{
+ return liblvm_lvm_pv_from_N(self, arg, lvm_pv_from_name);
+}
+
+static PyObject *
+liblvm_lvm_pv_from_uuid(vgobject *self, PyObject *arg)
+{
+ return liblvm_lvm_pv_from_N(self, arg, lvm_pv_from_uuid);
+}
+
+static void
+liblvm_pv_dealloc(pvobject *self)
+{
+ PyObject_Del(self);
+}
+
+/* LV Methods */
+
+#define LV_VALID(lvobject) \
+ do { \
+ if (!lvobject->lv) { \
+ PyErr_SetString(PyExc_UnboundLocalError, "LV object invalid"); \
+ return NULL; \
+ } \
+ } while (0)
+
+
+static PyObject *
+liblvm_lvm_lv_get_name(lvobject *self)
+{
+ LV_VALID(self);
+
+ return Py_BuildValue("s", lvm_lv_get_name(self->lv));
+}
+
+static PyObject *
+liblvm_lvm_lv_get_uuid(lvobject *self)
+{
+ LV_VALID(self);
+
+ return Py_BuildValue("s", lvm_lv_get_uuid(self->lv));
+}
+
+static PyObject *
+liblvm_lvm_lv_activate(lvobject *self)
+{
+ int rval;
+
+ LV_VALID(self);
+
+ if ((rval = lvm_lv_activate(self->lv)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_lv_deactivate(lvobject *self)
+{
+ int rval;
+
+ LV_VALID(self);
+
+ if ((rval = lvm_lv_deactivate(self->lv)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_vg_remove_lv(lvobject *self)
+{
+ int rval;
+
+ LV_VALID(self);
+
+ if ((rval = lvm_vg_remove_lv(self->lv)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ self->lv = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* This will return a tuple of (value, bool) with the value being a string or
+ integer and bool indicating if property is settable */
+static PyObject *
+liblvm_lvm_lv_get_property(lvobject *self, PyObject *args)
+{
+ const char *name;
+ struct lvm_property_value prop_value;
+
+ LV_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ prop_value = lvm_lv_get_property(self->lv, name);
+ return get_property(self->lvm_obj, &prop_value);
+}
+
+static PyObject *
+liblvm_lvm_lv_get_size(lvobject *self)
+{
+ LV_VALID(self);
+
+ return Py_BuildValue("l", lvm_lv_get_size(self->lv));
+}
+
+static PyObject *
+liblvm_lvm_lv_is_active(lvobject *self)
+{
+ PyObject *rval;
+
+ LV_VALID(self);
+
+ rval = ( lvm_lv_is_active(self->lv) == 1) ? Py_True : Py_False;
+
+ Py_INCREF(rval);
+ return rval;
+}
+
+static PyObject *
+liblvm_lvm_lv_is_suspended(lvobject *self)
+{
+ PyObject *rval;
+
+ LV_VALID(self);
+
+ rval = ( lvm_lv_is_suspended(self->lv) == 1) ? Py_True : Py_False;
+
+ Py_INCREF(rval);
+ return rval;
+}
+
+static PyObject *
+liblvm_lvm_lv_add_tag(lvobject *self, PyObject *args)
+{
+ const char *tag;
+ int rval;
+
+ LV_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &tag)) {
+ return NULL;
+ }
+
+ if ((rval = lvm_lv_add_tag(self->lv, tag)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_lv_remove_tag(lvobject *self, PyObject *args)
+{
+ const char *tag;
+ int rval;
+
+ LV_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &tag)) {
+ return NULL;
+ }
+
+ if ((rval = lvm_lv_remove_tag(self->lv, tag)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_lv_get_tags(lvobject *self)
+{
+ struct dm_list *tags;
+ struct lvm_str_list *strl;
+ PyObject * pytuple;
+ int i = 0;
+
+ LV_VALID(self);
+
+ tags = lvm_lv_get_tags(self->lv);
+ if (!tags) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ pytuple = PyTuple_New(dm_list_size(tags));
+ if (!pytuple)
+ return NULL;
+
+ dm_list_iterate_items(strl, tags) {
+ PyTuple_SET_ITEM(pytuple, i, PyString_FromString(strl->str));
+ i++;
+ }
+
+ return pytuple;
+}
+
+static PyObject *
+liblvm_lvm_lv_rename(lvobject *self, PyObject *args)
+{
+ const char *new_name;
+ int rval;
+
+ LV_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &new_name))
+ return NULL;
+
+ if ((rval = lvm_lv_rename(self->lv, new_name)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_lv_resize(lvobject *self, PyObject *args)
+{
+ uint64_t new_size;
+ int rval;
+
+ LV_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "l", &new_size)) {
+ return NULL;
+ }
+
+ if ((rval = lvm_lv_resize(self->lv, new_size)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_lv_list_lvsegs(lvobject *lv)
+{
+ struct dm_list *lvsegs;
+ lvseg_list_t *lvsegl;
+ PyObject * pytuple;
+ lvsegobject *self;
+ int i = 0;
+
+ LV_VALID(lv);
+
+ lvsegs = lvm_lv_list_lvsegs(lv->lv);
+ if(!lvsegs) {
+ return Py_BuildValue("()");
+ }
+
+ pytuple = PyTuple_New(dm_list_size(lvsegs));
+ if (!pytuple)
+ return NULL;
+
+ dm_list_iterate_items(lvsegl, lvsegs) {
+ /* Create and initialize the object */
+ self = PyObject_New(lvsegobject, &LibLVMlvsegType);
+ if (!self) {
+ Py_DECREF(pytuple);
+ return NULL;
+ }
+
+ self->lv_seg = lvsegl->lvseg;
+ self->lvm_obj = lv->lvm_obj;
+ PyTuple_SET_ITEM(pytuple, i, (PyObject *) self);
+ i++;
+ }
+
+ return pytuple;
+}
+
+/* PV Methods */
+
+#define PV_VALID(pvobject) \
+ do { \
+ if (!pvobject->pv || !pvobject->lvm_obj) { \
+ PyErr_SetString(PyExc_UnboundLocalError, "PV object invalid"); \
+ return NULL; \
+ } \
+ } while (0)
+
+static PyObject *
+liblvm_lvm_pv_get_name(pvobject *self)
+{
+ return Py_BuildValue("s", lvm_pv_get_name(self->pv));
+}
+
+static PyObject *
+liblvm_lvm_pv_get_uuid(pvobject *self)
+{
+ return Py_BuildValue("s", lvm_pv_get_uuid(self->pv));
+}
+
+static PyObject *
+liblvm_lvm_pv_get_mda_count(pvobject *self)
+{
+ return Py_BuildValue("l", lvm_pv_get_mda_count(self->pv));
+}
+
+static PyObject *
+liblvm_lvm_pv_get_property(pvobject *self, PyObject *args)
+{
+ const char *name;
+ struct lvm_property_value prop_value;
+
+ PV_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ prop_value = lvm_pv_get_property(self->pv, name);
+ return get_property(self->lvm_obj, &prop_value);
+}
+
+static PyObject *
+liblvm_lvm_pv_get_dev_size(pvobject *self)
+{
+ return Py_BuildValue("l", lvm_pv_get_dev_size(self->pv));
+}
+
+static PyObject *
+liblvm_lvm_pv_get_size(pvobject *self)
+{
+ return Py_BuildValue("l", lvm_pv_get_size(self->pv));
+}
+
+static PyObject *
+liblvm_lvm_pv_get_free(pvobject *self)
+{
+ return Py_BuildValue("l", lvm_pv_get_free(self->pv));
+}
+
+static PyObject *
+liblvm_lvm_pv_resize(pvobject *self, PyObject *args)
+{
+ uint64_t new_size;
+ int rval;
+
+ if (!PyArg_ParseTuple(args, "l", &new_size)) {
+ return NULL;
+ }
+
+ if ((rval = lvm_pv_resize(self->pv, new_size)) == -1) {
+ PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+liblvm_lvm_lv_list_pvsegs(pvobject *pv)
+{
+ struct dm_list *pvsegs;
+ pvseg_list_t *pvsegl;
+ PyObject *pytuple;
+ pvsegobject *self;
+ int i = 0;
+
+ PV_VALID(pv);
+
+ pvsegs = lvm_pv_list_pvsegs(pv->pv);
+ if(!pvsegs) {
+ return Py_BuildValue("()");
+ }
+
+ pytuple = PyTuple_New(dm_list_size(pvsegs));
+ if (!pytuple)
+ return NULL;
+
+ dm_list_iterate_items(pvsegl, pvsegs) {
+ /* Create and initialize the object */
+ self = PyObject_New(pvsegobject, &LibLVMpvsegType);
+ if (!self) {
+ Py_DECREF(pytuple);
+ return NULL;
+ }
+
+ self->pv_seg = pvsegl->pvseg;
+ self->lvm_obj = pv->lvm_obj;
+ PyTuple_SET_ITEM(pytuple, i, (PyObject *) self);
+ i++;
+ }
+
+ return pytuple;
+}
+
+/* LV seg methods */
+
+static void
+liblvm_lvseg_dealloc(lvsegobject *self)
+{
+ PyObject_Del(self);
+}
+
+static PyObject *
+liblvm_lvm_lvseg_get_property(lvsegobject *self, PyObject *args)
+{
+ const char *name;
+ struct lvm_property_value prop_value;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ prop_value = lvm_lvseg_get_property(self->lv_seg, name);
+ return get_property(self->lvm_obj, &prop_value);
+}
+
+/* PV seg methods */
+
+static void
+liblvm_pvseg_dealloc(pvsegobject *self)
+{
+ PyObject_Del(self);
+}
+
+static PyObject *
+liblvm_lvm_pvseg_get_property(pvsegobject *self, PyObject *args)
+{
+ const char *name;
+ struct lvm_property_value prop_value;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ prop_value = lvm_pvseg_get_property(self->pv_seg, name);
+ return get_property(self->lvm_obj, &prop_value);
+}
+
+/* ----------------------------------------------------------------------
+ * Method tables and other bureaucracy
+ */
+
+static PyMethodDef Liblvm_methods[] = {
+ /* LVM methods */
+ { "getVersion", (PyCFunction)liblvm_library_get_version, METH_NOARGS },
+ { "vgOpen", (PyCFunction)liblvm_lvm_vg_open, METH_VARARGS },
+ { "vgCreate", (PyCFunction)liblvm_lvm_vg_create, METH_VARARGS },
+ { "close", (PyCFunction)liblvm_close, METH_NOARGS },
+ { "configFindBool", (PyCFunction)liblvm_lvm_config_find_bool, METH_VARARGS },
+ { "configReload", (PyCFunction)liblvm_lvm_config_reload, METH_NOARGS },
+ { "configOverride", (PyCFunction)liblvm_lvm_config_override, METH_VARARGS },
+ { "scan", (PyCFunction)liblvm_lvm_scan, METH_NOARGS },
+ { "listVgNames", (PyCFunction)liblvm_lvm_list_vg_names, METH_NOARGS },
+ { "listVgUuids", (PyCFunction)liblvm_lvm_list_vg_uuids, METH_NOARGS },
+ { "percentToFloat", (PyCFunction)liblvm_lvm_percent_to_float, METH_VARARGS },
+ { "vgNameFromPvid", (PyCFunction)liblvm_lvm_vgname_from_pvid, METH_VARARGS },
+ { "vgNameFromDevice", (PyCFunction)liblvm_lvm_vgname_from_device, METH_VARARGS },
+ { NULL, NULL} /* sentinel */
+};
+
+static PyMethodDef liblvm_vg_methods[] = {
+ /* vg methods */
+ { "getName", (PyCFunction)liblvm_lvm_vg_get_name, METH_NOARGS },
+ { "getUuid", (PyCFunction)liblvm_lvm_vg_get_uuid, METH_NOARGS },
+ { "close", (PyCFunction)liblvm_lvm_vg_close, METH_NOARGS },
+ { "remove", (PyCFunction)liblvm_lvm_vg_remove, METH_NOARGS },
+ { "extend", (PyCFunction)liblvm_lvm_vg_extend, METH_VARARGS },
+ { "reduce", (PyCFunction)liblvm_lvm_vg_reduce, METH_VARARGS },
+ { "addTag", (PyCFunction)liblvm_lvm_vg_add_tag, METH_VARARGS },
+ { "removeTag", (PyCFunction)liblvm_lvm_vg_remove_tag, METH_VARARGS },
+ { "setExtentSize", (PyCFunction)liblvm_lvm_vg_set_extent_size, METH_VARARGS },
+ { "isClustered", (PyCFunction)liblvm_lvm_vg_is_clustered, METH_NOARGS },
+ { "isExported", (PyCFunction)liblvm_lvm_vg_is_exported, METH_NOARGS },
+ { "isPartial", (PyCFunction)liblvm_lvm_vg_is_partial, METH_NOARGS },
+ { "getSeqno", (PyCFunction)liblvm_lvm_vg_get_seqno, METH_NOARGS },
+ { "getSize", (PyCFunction)liblvm_lvm_vg_get_size, METH_NOARGS },
+ { "getFreeSize", (PyCFunction)liblvm_lvm_vg_get_free_size, METH_NOARGS },
+ { "getExtentSize", (PyCFunction)liblvm_lvm_vg_get_extent_size, METH_NOARGS },
+ { "getExtentCount", (PyCFunction)liblvm_lvm_vg_get_extent_count, METH_NOARGS },
+ { "getFreeExtentCount", (PyCFunction)liblvm_lvm_vg_get_free_extent_count, METH_NOARGS },
+ { "getProperty", (PyCFunction)liblvm_lvm_vg_get_property, METH_VARARGS },
+ { "setProperty", (PyCFunction)liblvm_lvm_vg_set_property, METH_VARARGS },
+ { "getPvCount", (PyCFunction)liblvm_lvm_vg_get_pv_count, METH_NOARGS },
+ { "getMaxPv", (PyCFunction)liblvm_lvm_vg_get_max_pv, METH_NOARGS },
+ { "getMaxLv", (PyCFunction)liblvm_lvm_vg_get_max_lv, METH_NOARGS },
+ { "listLVs", (PyCFunction)liblvm_lvm_vg_list_lvs, METH_NOARGS },
+ { "listPVs", (PyCFunction)liblvm_lvm_vg_list_pvs, METH_NOARGS },
+ { "lvFromName", (PyCFunction)liblvm_lvm_lv_from_name, METH_VARARGS },
+ { "lvFromUuid", (PyCFunction)liblvm_lvm_lv_from_uuid, METH_VARARGS },
+ { "pvFromName", (PyCFunction)liblvm_lvm_pv_from_name, METH_VARARGS },
+ { "pvFromUuid", (PyCFunction)liblvm_lvm_pv_from_uuid, METH_VARARGS },
+ { "getTags", (PyCFunction)liblvm_lvm_vg_get_tags, METH_NOARGS },
+ { "createLvLinear", (PyCFunction)liblvm_lvm_vg_create_lv_linear, METH_VARARGS },
+ { NULL, NULL} /* sentinel */
+};
+
+static PyMethodDef liblvm_lv_methods[] = {
+ /* lv methods */
+ { "getName", (PyCFunction)liblvm_lvm_lv_get_name, METH_NOARGS },
+ { "getUuid", (PyCFunction)liblvm_lvm_lv_get_uuid, METH_NOARGS },
+ { "activate", (PyCFunction)liblvm_lvm_lv_activate, METH_NOARGS },
+ { "deactivate", (PyCFunction)liblvm_lvm_lv_deactivate, METH_NOARGS },
+ { "remove", (PyCFunction)liblvm_lvm_vg_remove_lv, METH_NOARGS },
+ { "getProperty", (PyCFunction)liblvm_lvm_lv_get_property, METH_VARARGS },
+ { "getSize", (PyCFunction)liblvm_lvm_lv_get_size, METH_NOARGS },
+ { "isActive", (PyCFunction)liblvm_lvm_lv_is_active, METH_NOARGS },
+ { "isSuspended", (PyCFunction)liblvm_lvm_lv_is_suspended, METH_NOARGS },
+ { "addTag", (PyCFunction)liblvm_lvm_lv_add_tag, METH_VARARGS },
+ { "removeTag", (PyCFunction)liblvm_lvm_lv_remove_tag, METH_VARARGS },
+ { "getTags", (PyCFunction)liblvm_lvm_lv_get_tags, METH_NOARGS },
+ { "rename", (PyCFunction)liblvm_lvm_lv_rename, METH_VARARGS },
+ { "resize", (PyCFunction)liblvm_lvm_lv_resize, METH_VARARGS },
+ { "listLVsegs", (PyCFunction)liblvm_lvm_lv_list_lvsegs, METH_NOARGS },
+ { NULL, NULL} /* sentinel */
+};
+
+static PyMethodDef liblvm_pv_methods[] = {
+ /* pv methods */
+ { "getName", (PyCFunction)liblvm_lvm_pv_get_name, METH_NOARGS },
+ { "getUuid", (PyCFunction)liblvm_lvm_pv_get_uuid, METH_NOARGS },
+ { "getMdaCount", (PyCFunction)liblvm_lvm_pv_get_mda_count, METH_NOARGS },
+ { "getProperty", (PyCFunction)liblvm_lvm_pv_get_property, METH_VARARGS },
+ { "getSize", (PyCFunction)liblvm_lvm_pv_get_size, METH_NOARGS },
+ { "getDevSize", (PyCFunction)liblvm_lvm_pv_get_dev_size, METH_NOARGS },
+ { "getFree", (PyCFunction)liblvm_lvm_pv_get_free, METH_NOARGS },
+ { "resize", (PyCFunction)liblvm_lvm_pv_resize, METH_VARARGS },
+ { "listPVsegs", (PyCFunction)liblvm_lvm_lv_list_pvsegs, METH_NOARGS },
+ { NULL, NULL} /* sentinel */
+};
+
+static PyMethodDef liblvm_lvseg_methods[] = {
+ { "getProperty", (PyCFunction)liblvm_lvm_lvseg_get_property, METH_VARARGS },
+ { NULL, NULL} /* sentinel */
+};
+
+static PyMethodDef liblvm_pvseg_methods[] = {
+ { "getProperty", (PyCFunction)liblvm_lvm_pvseg_get_property, METH_VARARGS },
+ { NULL, NULL} /* sentinel */
+};
+
+static PyTypeObject LiblvmType = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ .tp_name = "liblvm.Liblvm",
+ .tp_basicsize = sizeof(lvmobject),
+ .tp_new = PyType_GenericNew,
+ .tp_dealloc = (destructor)liblvm_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_doc = "Liblvm objects",
+ .tp_methods = Liblvm_methods,
+ .tp_init = (initproc)liblvm_init,
+};
+
+static PyTypeObject LibLVMvgType = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ .tp_name = "liblvm.Liblvm_vg",
+ .tp_basicsize = sizeof(vgobject),
+ .tp_new = PyType_GenericNew,
+ .tp_dealloc = (destructor)liblvm_vg_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "LVM Volume Group object",
+ .tp_methods = liblvm_vg_methods,
+};
+
+static PyTypeObject LibLVMlvType = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ .tp_name = "liblvm.Liblvm_lv",
+ .tp_basicsize = sizeof(lvobject),
+ .tp_new = PyType_GenericNew,
+ .tp_dealloc = (destructor)liblvm_lv_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "LVM Logical Volume object",
+ .tp_methods = liblvm_lv_methods,
+};
+
+static PyTypeObject LibLVMpvType = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ .tp_name = "liblvm.Liblvm_pv",
+ .tp_basicsize = sizeof(pvobject),
+ .tp_new = PyType_GenericNew,
+ .tp_dealloc = (destructor)liblvm_pv_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "LVM Physical Volume object",
+ .tp_methods = liblvm_pv_methods,
+};
+
+static PyTypeObject LibLVMlvsegType = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ .tp_name = "liblvm.Liblvm_lvseg",
+ .tp_basicsize = sizeof(lvsegobject),
+ .tp_new = PyType_GenericNew,
+ .tp_dealloc = (destructor)liblvm_lvseg_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "LVM Logical Volume Segment object",
+ .tp_methods = liblvm_lvseg_methods,
+};
+
+static PyTypeObject LibLVMpvsegType = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ .tp_name = "liblvm.Liblvm_pvseg",
+ .tp_basicsize = sizeof(pvsegobject),
+ .tp_new = PyType_GenericNew,
+ .tp_dealloc = (destructor)liblvm_pvseg_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "LVM Physical Volume Segment object",
+ .tp_methods = liblvm_pvseg_methods,
+};
+
+PyMODINIT_FUNC
+initlvm(void)
+{
+ PyObject *m;
+
+ if (PyType_Ready(&LiblvmType) < 0)
+ return;
+ if (PyType_Ready(&LibLVMvgType) < 0)
+ return;
+ if (PyType_Ready(&LibLVMlvType) < 0)
+ return;
+ if (PyType_Ready(&LibLVMpvType) < 0)
+ return;
+ if (PyType_Ready(&LibLVMlvsegType) < 0)
+ return;
+ if (PyType_Ready(&LibLVMpvsegType) < 0)
+ return;
+
+ m = Py_InitModule3("lvm", Liblvm_methods, "Liblvm module");
+ if (m == NULL)
+ return;
+
+ Py_INCREF(&LiblvmType);
+ PyModule_AddObject(m, "Liblvm", (PyObject *)&LiblvmType);
+
+ LibLVMError = PyErr_NewException("Liblvm.LibLVMError",
+ NULL, NULL);
+ if (LibLVMError) {
+ /* Each call to PyModule_AddObject decrefs it; compensate: */
+ Py_INCREF(LibLVMError);
+ Py_INCREF(LibLVMError);
+ PyModule_AddObject(m, "error", LibLVMError);
+ PyModule_AddObject(m, "LibLVMError", LibLVMError);
+ }
+
+}
diff --git a/python/setup.py.in b/python/setup.py.in
new file mode 100644
index 0000000..6a44482
--- /dev/null
+++ b/python/setup.py.in
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM2.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from distutils.core import setup, Extension
+
+liblvm = Extension('lvm',
+ sources = ['liblvm_python.c'],
+ libraries= ['lvm2app'],
+ library_dirs= ['@top_builddir@/liblvm'],
+ include_dirs= ['@top_builddir@/include'])
+
+setup (name='lvm',
+ version=@LVM_VERSION@,
+ description='Python bindings for liblvm2',
+ license="LGPLv2+",
+ maintainer='LVM2 maintainers',
+ maintainer_email='linux-lvm(a)redhat.com',
+ url='http://sourceware.org/lvm2/',
+ ext_modules=[liblvm],
+)
11 years, 6 months
master - lvmdump: Add -l, to collect a state dump from lvmetad.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4022fd3e79099f...
Commit: 4022fd3e79099fb22b2b7d3d6dca8de733a2a783
Parent: 8557b412f679f1a9c8edb91e43b35793645c901e
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Thu Oct 11 22:42:20 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Thu Oct 11 22:42:20 2012 +0200
lvmdump: Add -l, to collect a state dump from lvmetad.
---
scripts/lvmdump.sh | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/scripts/lvmdump.sh b/scripts/lvmdump.sh
index 5901892..641d109 100755
--- a/scripts/lvmdump.sh
+++ b/scripts/lvmdump.sh
@@ -33,11 +33,14 @@ BASENAME=basename
UDEVADM=udevadm
UNAME=uname
TR=tr
+SOCAT=socat # either socat or nc is needed for dumping lvmetad state
+NC=nc
# user may override lvm and dmsetup location by setting LVM_BINARY
# and DMSETUP_BINARY respectively
LVM=${LVM_BINARY-lvm}
DMSETUP=${DMSETUP_BINARY-dmsetup}
+LVMETAD_SOCKET=${LVM_LVMETAD_SOCKET-/var/run/lvm/lvmetad.socket}
die() {
code=$1; shift
@@ -57,6 +60,7 @@ function usage {
echo " -d <directory> dump into a directory instead of tarball"
echo " -c if running clvmd, gather cluster data as well"
echo " -u gather udev info and context"
+ echo " -l gather lvmetad state if running"
echo ""
exit 1
@@ -66,7 +70,7 @@ advanced=0
clustered=0
metadata=0
udev=0
-while getopts :acd:hmu opt; do
+while getopts :acd:hmul opt; do
case $opt in
s) sysreport=1 ;;
a) advanced=1 ;;
@@ -75,6 +79,7 @@ while getopts :acd:hmu opt; do
h) usage ;;
m) metadata=1 ;;
u) udev=1 ;;
+ l) lvmetad=1 ;;
:) echo "$0: $OPTARG requires a value:"; usage ;;
\?) echo "$0: unknown option $OPTARG"; usage ;;
*) usage ;;
@@ -240,6 +245,22 @@ if (( $udev )); then
log "$CP -aR /lib/udev/rules.d \"$udev_dir/rules_lib\" 2>> \"$log\""
fi
+if (( $lvmetad )); then
+ (echo 'request="dump"'; echo '##') | {
+ if type -p $SOCAT >& /dev/null; then
+ echo "$SOCAT unix-connect:$LVMETAD_SOCKET -" >> "$log"
+ $SOCAT "unix-connect:$LVMETAD_SOCKET" - 2>> "$log"
+ elif echo | $NC -U "$LVMETAD_SOCKET"; then
+ echo "$NC -U $LVMETAD_SOCKET" >> "$log"
+ $NC -U "$LVMETAD_SOCKET" 2>> "$log"
+ else
+ myecho "WARNING: Neither socat nor nc -U seems to be available." 1>&2
+ echo "# DUMP FAILED"
+ return 1
+ fi
+ } > "$dir/lvmetad.txt"
+fi
+
if test -z "$userdir"; then
lvm_dump="$dirbase.tgz"
myecho "Creating report tarball in $HOME/$lvm_dump..."
11 years, 6 months
master - lvmdump: Fix systems with tr on PATH outside of /usr/bin.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8557b412f679f1...
Commit: 8557b412f679f1a9c8edb91e43b35793645c901e
Parent: 413d91dc29a41b44c80df5ff5d054b36895718eb
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Thu Oct 11 22:39:40 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Thu Oct 11 22:40:58 2012 +0200
lvmdump: Fix systems with tr on PATH outside of /usr/bin.
---
scripts/lvmdump.sh | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/scripts/lvmdump.sh b/scripts/lvmdump.sh
index 5e764f2..5901892 100755
--- a/scripts/lvmdump.sh
+++ b/scripts/lvmdump.sh
@@ -32,6 +32,7 @@ DATE=date
BASENAME=basename
UDEVADM=udevadm
UNAME=uname
+TR=tr
# user may override lvm and dmsetup location by setting LVM_BINARY
# and DMSETUP_BINARY respectively
@@ -80,7 +81,7 @@ while getopts :acd:hmu opt; do
esac
done
-NOW=`$DATE -u +%G%m%d%k%M%S | /usr/bin/tr -d ' '`
+NOW=`$DATE -u +%G%m%d%k%M%S | $TR -d ' '`
if test -n "$userdir"; then
dir="$userdir"
else
11 years, 6 months
master - test: Add lvmetad-dump.sh.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=413d91dc29a41b...
Commit: 413d91dc29a41b44c80df5ff5d054b36895718eb
Parent: a63b46bf36b22b83ff05f2d3529bc22a38ff56d3
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Thu Oct 11 20:32:25 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Thu Oct 11 20:32:25 2012 +0200
test: Add lvmetad-dump.sh.
---
test/shell/lvmetad-dump.sh | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/test/shell/lvmetad-dump.sh b/test/shell/lvmetad-dump.sh
new file mode 100644
index 0000000..e49eb68
--- /dev/null
+++ b/test/shell/lvmetad-dump.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+. lib/test
+test -e LOCAL_LVMETAD || skip
+
+aux prepare_pvs 2
+vgcreate $vg1 $dev1 $dev2
+lvcreate -n bar -l 1 $vg1
+
+lvmetad_talk() {
+ if type -p socat >& /dev/null; then
+ socat "unix-connect:$1" -
+ elif echo | nc -U "$1"; then
+ nc -U "$1"
+ else
+ echo "WARNING: Neither socat nor nc -U seems to be available." 1>&2
+ echo "# DUMP FAILED"
+ return 1
+ fi
+}
+
+lvmetad_dump() {
+ (echo 'request="dump"'; echo '##') | lvmetad_talk "$@"
+}
+
+(echo | lvmetad_talk ./lvmetad.socket) || skip
+lvmetad_dump ./lvmetad.socket | tee lvmetad.txt
+
+grep $vg1 lvmetad.txt
11 years, 6 months