summaryrefslogtreecommitdiff
path: root/cmds-balance.c
diff options
context:
space:
mode:
authorAustin S. Hemmelgarn <ahferroin7@gmail.com>2016-06-21 11:16:59 -0400
committerDavid Sterba <dsterba@suse.com>2016-07-26 19:26:29 +0200
commitfe520b5cdc46bc7f34d55b16292d5be805ffd339 (patch)
tree661b1fec603b30711be21fa13e88e5fc208580be /cmds-balance.c
parent1d6c7cb725bb7d25981d44915b316e24751b7b72 (diff)
btrfs-progs: add option to run balance as daemon
Currently, balance operations are run synchronously in the foreground. This is nice for interactive management, but is kind of crappy when you start looking at automation and similar things. This patch adds an option to `btrfs balance start` to tell it to daemonize prior to running the balance operation, thus allowing us to preform balances asynchronously. The two biggest use cases I have for this are starting a balance on a remote server without establishing a full shell session, and being able to background the balance in a recovery shell (which usually has no job control) so I can still get progress information. Because it simply daemonizes prior to calling the balance ioctl, this doesn't actually need any kernel support. Signed-off-by: Austin S. Hemmelgarn <ahferroin7@gmail.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'cmds-balance.c')
-rw-r--r--cmds-balance.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/cmds-balance.c b/cmds-balance.c
index 374e9817..e9e388e8 100644
--- a/cmds-balance.c
+++ b/cmds-balance.c
@@ -20,6 +20,9 @@
#include <unistd.h>
#include <getopt.h>
#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <errno.h>
#include "kerncompat.h"
@@ -507,6 +510,7 @@ static const char * const cmd_balance_start_usage[] = {
"-v be verbose",
"-f force reducing of metadata integrity",
"--full-balance do not print warning and do not delay start",
+ "--background run the balance as a background process",
NULL
};
@@ -517,13 +521,15 @@ static int cmd_balance_start(int argc, char **argv)
&args.meta, NULL };
int force = 0;
int verbose = 0;
+ int background = 0;
unsigned start_flags = 0;
int i;
memset(&args, 0, sizeof(args));
while (1) {
- enum { GETOPT_VAL_FULL_BALANCE = 256 };
+ enum { GETOPT_VAL_FULL_BALANCE = 256,
+ GETOPT_VAL_BACKGROUND = 257 };
static const struct option longopts[] = {
{ "data", optional_argument, NULL, 'd'},
{ "metadata", optional_argument, NULL, 'm' },
@@ -532,6 +538,8 @@ static int cmd_balance_start(int argc, char **argv)
{ "verbose", no_argument, NULL, 'v' },
{ "full-balance", no_argument, NULL,
GETOPT_VAL_FULL_BALANCE },
+ { "background", no_argument, NULL,
+ GETOPT_VAL_BACKGROUND },
{ NULL, 0, NULL, 0 }
};
@@ -570,6 +578,9 @@ static int cmd_balance_start(int argc, char **argv)
case GETOPT_VAL_FULL_BALANCE:
start_flags |= BALANCE_START_NOWARN;
break;
+ case GETOPT_VAL_BACKGROUND:
+ background = 1;
+ break;
default:
usage(cmd_balance_start_usage);
}
@@ -622,6 +633,35 @@ static int cmd_balance_start(int argc, char **argv)
args.flags |= BTRFS_BALANCE_FORCE;
if (verbose)
dump_ioctl_balance_args(&args);
+ if (background) {
+ switch (fork()) {
+ case (-1):
+ error("unable to fork to run balance in background");
+ return 1;
+ case (0):
+ setsid();
+ switch(fork()) {
+ case (-1):
+ error(
+ "unable to fork to run balance in background");
+ exit(1);
+ case (0):
+ chdir("/");
+ close(0);
+ close(1);
+ close(2);
+ open("/dev/null", O_RDONLY);
+ open("/dev/null", O_WRONLY);
+ open("/dev/null", O_WRONLY);
+ break;
+ default:
+ exit(0);
+ }
+ break;
+ default:
+ exit(0);
+ }
+ }
return do_balance(argv[optind], &args, start_flags);
}