diff mbox

[v6,4/8] Run userspace tool in background for balances.

Message ID 5813d6898efdce8d0acb5f95e5bce70f991c2026.1304262467.git.hugo@carfax.org.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Hugo Mills May 1, 2011, 3:47 p.m. UTC
This patch makes a balance operation fork and detach from the current
terminal, to run the userspace side of the balance in the background.

Introduce a --wait switch so that a synchronous balance can be done if
the user requires.

Signed-off-by: Hugo Mills <hugo@carfax.org.uk>
---
 btrfs.c        |    8 ++++----
 btrfs_cmds.c   |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 man/btrfs.8.in |   14 ++++++++------
 3 files changed, 62 insertions(+), 12 deletions(-)
diff mbox

Patch

diff --git a/btrfs.c b/btrfs.c
index 93f7886..7b42658 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -91,12 +91,12 @@  static struct Command commands[] = {
 	  "filesystem df", "<path>\n"
 		"Show space usage information for a mount point\n."
 	},
-	{ do_balance, 1,
-	  "filesystem balance", "<path>\n"
+	{ do_balance, -1,
+	  "filesystem balance", "[-w|--wait] <path>\n"
 		"Balance the chunks across the device."
 	},
-	{ do_balance, 1,
-	  "balance start", "<path>\n"
+	{ do_balance, -1,
+	  "balance start", "[-w|--wait] <path>\n"
 		"Synonym for \"btrfs filesystem balance\"."
 	},
 	{ do_balance_progress, -1,
diff --git a/btrfs_cmds.c b/btrfs_cmds.c
index b1631a0..070b8a9 100644
--- a/btrfs_cmds.c
+++ b/btrfs_cmds.c
@@ -754,12 +754,41 @@  int do_add_volume(int nargs, char **args)
 
 }
 
+const struct option balance_options[] = {
+	{ "wait", 0, NULL, 'w' },
+	{ NULL, 0, NULL, 0 }
+};
+
 int do_balance(int argc, char **argv)
 {
-
 	int	fdmnt, ret=0;
+	int background = 1;
 	struct btrfs_ioctl_vol_args args;
-	char	*path = argv[1];
+	char *path;
+	int ttyfd;
+
+	optind = 1;
+	while(1) {
+		int c = getopt_long(argc, argv, "w", balance_options, NULL);
+		if (c < 0)
+			break;
+		switch(c) {
+		case 'w':
+			background = 0;
+			break;
+		default:
+			fprintf(stderr, "Invalid arguments for balance\n");
+			free(argv);
+			return 1;
+		}
+	}
+
+	if(optind >= argc) {
+		fprintf(stderr, "No filesystem path given for balance\n");
+		return 1;
+	}
+
+	path = argv[optind];
 
 	fdmnt = open_file_or_dir(path);
 	if (fdmnt < 0) {
@@ -767,6 +796,25 @@  int do_balance(int argc, char **argv)
 		return 12;
 	}
 
+	if (background) {
+		int pid = fork();
+		if (pid == 0) {
+			/* We're in the child, and can run in the background */
+			ttyfd = open("/dev/tty", O_RDWR);
+			if (ttyfd > 0)
+				ioctl(ttyfd, TIOCNOTTY, 0);
+			/* Fall through to the BTRFS_IOC_BALANCE ioctl */
+		} else if (pid > 0) {
+			/* We're in the parent, and the fork succeeded */
+			printf("Background balance started\n");
+			return 0;
+		} else {
+			/* We're in the parent, and the fork failed */
+			fprintf(stderr, "ERROR: can't start background process -- %s\n",
+					strerror(errno));
+		}
+	}
+
 	memset(&args, 0, sizeof(args));
 	ret = ioctl(fdmnt, BTRFS_IOC_BALANCE, &args);
 	close(fdmnt);
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 9c6bb69..77558fa 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -21,11 +21,11 @@  btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max <filesystem>\fP
 .PP
-\fBbtrfs\fP \fBfilesystem balance\fP\fI <path> \fP
+\fBbtrfs\fP \fBfilesystem balance\fP [\fB-w\fP|\fB--wait\fP] \fI<path>\fP
 .PP
 \fBbtrfs\fP \fBdevice scan\fP\fI [<device> [<device>..]]\fP
 .PP
-\fBbtrfs\fP \fBbalance start\fP\fI <path> \fP
+\fBbtrfs\fP \fBbalance start\fP [\fB-w\fP|\fB--wait\fP] \fI<path>\fP
 .PP
 \fBbtrfs\fP \fBbalance progress\fP [\fB-m\fP|\fB--monitor\fP] \fI<path>\fP
 .PP
@@ -149,11 +149,13 @@  Show the btrfs filesystem with some additional info. If no UUID or label is
 passed, \fBbtrfs\fR show info of all the btrfs filesystem.
 .TP
 
-\fBbalance start\fR \fI<path>\fR
+\fBdevice balance\fR [\fB-w\fP|\fB--wait\fP] \fI<path>\fR
 .TP
-\fBfilesystem balance\fR \fI<path>\fR
-Balance the chunks of the filesystem identified by \fI<path>\fR
-across the devices.
+\fBbalance start\fR [\fB-w\fP|\fB--wait\fP] \fI<path>\fR
+
+Balance the chunks of the filesystem identified by \fI<path>\fR across
+the devices. The process runs in the background. Use \fB--wait\fP to
+wait in the foreground for completion of the balance.
 .TP
 
 \fBdevice add\fR\fI <dev> [<dev>..] <path>\fR