summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--daemons/clvmd/lvm-functions.c2
-rw-r--r--lib/commands/toolcontext.c30
-rw-r--r--lib/commands/toolcontext.h4
-rw-r--r--liblvm/lvm_base.c2
-rw-r--r--tools/lvmcmdline.c2
5 files changed, 35 insertions, 5 deletions
diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
index 166cd7f1..8e68ed98 100644
--- a/daemons/clvmd/lvm-functions.c
+++ b/daemons/clvmd/lvm-functions.c
@@ -919,7 +919,7 @@ int init_clvm(int using_gulm, char **argv)
init_syslog(LOG_DAEMON);
openlog("clvmd", LOG_PID, LOG_DAEMON);
- if (!(cmd = create_toolcontext(1, NULL))) {
+ if (!(cmd = create_toolcontext(1, NULL, 0))) {
log_error("Failed to allocate command context");
return 0;
}
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 9b3e27f4..918362ce 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -58,6 +58,8 @@
# include <malloc.h>
#endif
+static const size_t linebuffer_size = 4096;
+
static int _get_env_vars(struct cmd_context *cmd)
{
const char *e;
@@ -1148,7 +1150,8 @@ static void _init_globals(struct cmd_context *cmd)
/* Entry point */
struct cmd_context *create_toolcontext(unsigned is_long_lived,
- const char *system_dir)
+ const char *system_dir,
+ unsigned set_buffering)
{
struct cmd_context *cmd;
@@ -1183,6 +1186,22 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
/* FIXME Make this configurable? */
reset_lvm_errno(1);
+ /* Set in/out stream buffering before glibc */
+ if (set_buffering) {
+ /* Allocate 2 buffers */
+ if (!(cmd->linebuffer = dm_malloc(2 * linebuffer_size))) {
+ log_error("Failed to allocate line buffer.");
+ goto out;
+ }
+ if ((setvbuf(stdin, cmd->linebuffer, _IOLBF, linebuffer_size) ||
+ setvbuf(stdout, cmd->linebuffer + linebuffer_size,
+ _IOLBF, linebuffer_size))) {
+ log_sys_error("setvbuf", "");
+ goto out;
+ }
+ /* Buffers are used for lines without '\n' */
+ }
+
/*
* Environment variable LVM_SYSTEM_DIR overrides this below.
*/
@@ -1419,6 +1438,15 @@ void destroy_toolcontext(struct cmd_context *cmd)
_destroy_tag_configs(cmd);
if (cmd->libmem)
dm_pool_destroy(cmd->libmem);
+
+ if (cmd->linebuffer) {
+ /* Reset stream buffering to defaults */
+ setlinebuf(stdin);
+ fflush(stdout);
+ setlinebuf(stdout);
+ dm_free(cmd->linebuffer);
+ }
+
dm_free(cmd);
release_log_memory();
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 4628c7c2..1c3368e6 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -66,6 +66,7 @@ struct cmd_context {
const char *kernel_vsn;
unsigned rand_seed;
+ char *linebuffer;
const char *cmd_line;
struct command *command;
char **argv;
@@ -109,7 +110,8 @@ struct cmd_context {
* The environment variable LVM_SYSTEM_DIR always takes precedence.
*/
struct cmd_context *create_toolcontext(unsigned is_long_lived,
- const char *system_dir);
+ const char *system_dir,
+ unsigned set_buffering);
void destroy_toolcontext(struct cmd_context *cmd);
int refresh_toolcontext(struct cmd_context *cmd);
int refresh_filters(struct cmd_context *cmd);
diff --git a/liblvm/lvm_base.c b/liblvm/lvm_base.c
index 9e1a8ecd..f44b786c 100644
--- a/liblvm/lvm_base.c
+++ b/liblvm/lvm_base.c
@@ -34,7 +34,7 @@ lvm_t lvm_init(const char *system_dir)
/* create context */
/* FIXME: split create_toolcontext */
/* FIXME: make all globals configurable */
- cmd = create_toolcontext(0, system_dir);
+ cmd = create_toolcontext(0, system_dir, 1);
if (!cmd)
return NULL;
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 197cd143..3e13a27d 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1282,7 +1282,7 @@ struct cmd_context *init_lvm(void)
if (!udev_init_library_context())
stack;
- if (!(cmd = create_toolcontext(0, NULL)))
+ if (!(cmd = create_toolcontext(0, NULL, 1)))
return_NULL;
_cmdline.arg_props = &_arg_props[0];