[PATCH 2/2] nilfs-utils: add new command nilfs-tune

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch add new commands named "nilfs-tune".
nilfs-tune modifys tunable NILFS parameters.
Currently supported parameters are:
- volume label
- UUID
- commit interval
- segment contsruction block max

It also displays NILFS super block information if specified.

Signed-off-by: Jiro SEKIBA <jir@xxxxxxxxx>
---
 configure.ac                 |    7 +-
 man/Makefile.am              |    2 +-
 man/chcp.8                   |    3 +-
 man/lscp.1                   |    3 +-
 man/mkcp.8                   |    3 +-
 man/nilfs-tune.8             |   54 +++++
 man/nilfs.8                  |    1 +
 man/rmcp.8                   |    3 +-
 sbin/Makefile.am             |    2 +-
 sbin/nilfs-tune/Makefile.am  |    9 +
 sbin/nilfs-tune/nilfs-tune.c |  500 ++++++++++++++++++++++++++++++++++++++++++
 11 files changed, 578 insertions(+), 9 deletions(-)
 create mode 100644 man/nilfs-tune.8
 create mode 100644 sbin/nilfs-tune/Makefile.am
 create mode 100644 sbin/nilfs-tune/nilfs-tune.c

diff --git a/configure.ac b/configure.ac
index 74dbae3..af75142 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,7 +37,7 @@ AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
 AC_CHECK_HEADERS([fcntl.h libintl.h limits.h locale.h mntent.h paths.h \
 		  stdlib.h string.h strings.h sys/ioctl.h sys/mount.h \
-		  sys/time.h syslog.h unistd.h linux/types.h])
+		  sys/time.h syslog.h unistd.h linux/types.h grp.h pwd.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -68,7 +68,7 @@ AC_FUNC_STRFTIME
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS([alarm atexit ftruncate getcwd gettimeofday localtime_r \
 		memmove memset munmap strchr strdup strerror strrchr strstr \
-		strtoul])
+		strtoul getgrgid getpwuid])
 
 # Checks for system services
 AC_SYS_LARGEFILE
@@ -87,5 +87,6 @@ AC_CONFIG_FILES([Makefile
 		 sbin/Makefile
 		 sbin/cleanerd/Makefile
 		 sbin/mkfs/Makefile
-		 sbin/mount/Makefile])
+		 sbin/mount/Makefile
+		 sbin/nilfs-tune/Makefile])
 AC_OUTPUT
diff --git a/man/Makefile.am b/man/Makefile.am
index 7085c86..3953f90 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -2,4 +2,4 @@
 
 dist_man_MANS = nilfs.8 mkfs.nilfs2.8 mount.nilfs2.8 umount.nilfs2.8 \
 	lscp.1 mkcp.8 chcp.8 rmcp.8 lssu.1 dumpseg.8 nilfs_cleanerd.8 \
-	nilfs_cleanerd.conf.5
+	nilfs_cleanerd.conf.5 nilfs-tune.8
diff --git a/man/chcp.8 b/man/chcp.8
index 65445f3..031e2eb 100644
--- a/man/chcp.8
+++ b/man/chcp.8
@@ -33,4 +33,5 @@ http://www.nilfs.org.
 .BR nilfs (8),
 .BR lscp (1),
 .BR mkcp (8),
-.BR rmcp (8).
+.BR rmcp (8),
+.BR nilfs-tune (8).
diff --git a/man/lscp.1 b/man/lscp.1
index 73ffc9a..0513f57 100644
--- a/man/lscp.1
+++ b/man/lscp.1
@@ -70,4 +70,5 @@ http://www.nilfs.org.
 .BR nilfs (8),
 .BR mkcp (8),
 .BR chcp (8),
-.BR rmcp (8).
+.BR rmcp (8),
+.BR nilfs-tune (8).
diff --git a/man/mkcp.8 b/man/mkcp.8
index 20e1848..490a75b 100644
--- a/man/mkcp.8
+++ b/man/mkcp.8
@@ -32,4 +32,5 @@ http://www.nilfs.org.
 .BR nilfs (8),
 .BR lscp (1),
 .BR chcp (8),
-.BR rmcp (8).
+.BR rmcp (8),
+.BR nilfs-tune (8).
diff --git a/man/nilfs-tune.8 b/man/nilfs-tune.8
new file mode 100644
index 0000000..2337c8f
--- /dev/null
+++ b/man/nilfs-tune.8
@@ -0,0 +1,54 @@
+.\"  Copyright (C) 2010 Jiro SEKIBA <jir@xxxxxxxxx>
+.\"
+.TH NILFS-TUNE 8 "May 2010" "nilfs-utils version 2.0"
+.SH NAME
+nilfs-tune \- adjust tunable file system parameters on NILFS filesystem
+.SH SYNOPSIS
+.B nilfs-tune
+[\fIoptions\fP] \fIdevice\fP
+.SH DESCRIPTION
+.B nilfs-tune
+is a utility to modify tunable file system parameters on NILFS2 file
+system in \fIdevice\fP.  When \fIdevice\fP is omitted, it tries
+to find a NILFS2 file system from \fI/proc/mounts\fP.
+.PP
+This command is valid only for mounted NILFS2 file systems, and
+will fail if the \fIdevice\fP has no active mounts.
+.SH OPTIONS
+.TP
+.B \-i \fIinterval\fP
+Set the commit interval of segment.
+.TP
+.B \-m \fIblock-max\fP
+Set the threshold of the data amount of the segment construction.
+.TP
+.B \-l
+List the contents of the file system superblock, including the current
+values of the prameters that can be set via this program.
+.TP
+.B \-L \fIvolume-label\fP
+Set the volume label of the file system.  NILFS2 file system labels
+can be at most 80 bytes long.  If volume-label is longer than 80 bytes,
+nilfs-tune will truncate it.  The volume label can be used mount(8) and
+/etc/fstab(5) (and possibly others) by specifying \fBLABEL\fP=volume-label
+instead of a block special device name like /dev/sda5.
+.TP
+.B \-U \fIUUID\fP
+Set the universally unique identifier (UUID) of the filesystem to UUID.
+The format of the UUID is a series of hex digits sepa rated by hyphens,
+like this: "c1b9d5a2-f162-11cf-9ece-0020afc76f16".
+.TP
+.B \-h
+Display help message and exit.
+.SH AUTHOR
+Jiro SEKIBA <jir@xxxxxxxxx>
+.SH AVAILABILITY
+.B nilfs-tune
+is part of the nilfs-utils package and is available from
+http://www.nilfs.org.
+.SH SEE ALSO
+.BR nilfs (8),
+.BR lscp (1),
+.BR chcp (8),
+.BR mkcp (8),
+.BR rmcp (8).
diff --git a/man/nilfs.8 b/man/nilfs.8
index 8ec8f13..e8089e6 100644
--- a/man/nilfs.8
+++ b/man/nilfs.8
@@ -111,6 +111,7 @@ was developed by NILFS development team <nilfs@xxxxxxxx>.
 .BR umount.nilfs2 (8),
 .BR nilfs_cleanerd (8),
 .BR nilfs_cleanerd.conf (5),
+.BR nilfs-tune (8),
 .BR lscp (1),
 .BR mkcp (8),
 .BR chcp (8),
diff --git a/man/rmcp.8 b/man/rmcp.8
index e7d65f9..6d99a21 100644
--- a/man/rmcp.8
+++ b/man/rmcp.8
@@ -52,4 +52,5 @@ http://www.nilfs.org.
 .BR nilfs (8),
 .BR lscp (1),
 .BR mkcp (8),
-.BR chcp (8).
+.BR chcp (8),
+.BR nilfs-tune (8).
diff --git a/sbin/Makefile.am b/sbin/Makefile.am
index 6038b8f..0783ce0 100644
--- a/sbin/Makefile.am
+++ b/sbin/Makefile.am
@@ -1,3 +1,3 @@
 ## Makefile.am
 
-SUBDIRS = cleanerd mkfs mount
+SUBDIRS = cleanerd mkfs mount nilfs-tune
diff --git a/sbin/nilfs-tune/Makefile.am b/sbin/nilfs-tune/Makefile.am
new file mode 100644
index 0000000..e29ba2e
--- /dev/null
+++ b/sbin/nilfs-tune/Makefile.am
@@ -0,0 +1,9 @@
+## Makefile.am
+
+AM_CFLAGS = -Wall
+AM_CPPFLAGS = -I$(top_srcdir)/include
+
+sbin_PROGRAMS = nilfs-tune
+
+nilfs_tune_SOURCES = nilfs-tune.c
+nilfs_tune_LDADD = $(top_builddir)/lib/libnilfs.la
diff --git a/sbin/nilfs-tune/nilfs-tune.c b/sbin/nilfs-tune/nilfs-tune.c
new file mode 100644
index 0000000..99abb56
--- /dev/null
+++ b/sbin/nilfs-tune/nilfs-tune.c
@@ -0,0 +1,500 @@
+/*
+ * nilfs-tune.c - adjust tunable filesystem parameters on NILFS filesystem
+ *
+ * Copyright (C) 2010 Jiro SEKIBA <jir@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NILFS; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif	/* HAVE_CONFIG_H */
+
+#define _FILE_OFFSET_BITS 64
+//#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#define __USE_FILE_OFFSET64
+#define _XOPEN_SOURCE 600
+
+#include <stdio.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif	/* HAVE_STDLIB_H */
+
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif	/* HAVE_STRINGS_H */
+
+#if HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif	/* HAVE_SYS_IOCTL_H */
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif	/* HAVE_STRING_H */
+
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif	/* HAVE_LIMITS_H */
+
+#if HAVE_GRP_H
+#include <grp.h>
+#endif	/* HAVE_GRP_H */
+
+#if HAVE_PWD_H
+#include <pwd.h>
+#endif	/* HAVE_PWD_H */
+
+#include <ctype.h>
+
+#include <errno.h>
+#include "nilfs.h"
+
+#define MOUNTS			"/etc/mtab"
+#define LINE_BUFFER_SIZE	256  /* Line buffer size for reading mtab */
+
+struct nilfs_tune_options {
+	int flags;
+	int display;
+	int mask;
+	int force;
+	__u32 c_interval;
+	__u32 c_block_max;
+	char label[80];
+	__u8 uuid[16];
+};
+
+static void nilfs_tune_usage(void)
+{
+	printf("Usage: nilfs-tune [-h] [-l] [-i interval] [-L volume_name]\n"
+	       "                  [-m block_max] [-U UUID] device\n");
+}
+
+int parse_uuid(const char *uuid_string, __u8 *uuid)
+{
+	int i;
+	char p[3];
+
+	if (strlen(uuid_string) != 36)
+		return -1;
+
+	for (i=0, p[2]='\0'; i < 36; i++) {
+		if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) {
+			if (uuid_string[i] == '-')
+				continue;
+			else
+				return -1;
+		}
+		if (!isxdigit(uuid_string[i]) || !isxdigit(uuid_string[i+1]))
+			return -1;
+
+		p[0] = uuid_string[i++];
+		p[1] = uuid_string[i];
+		*uuid = strtoul(p, NULL, 16);
+		uuid++;
+	}
+	return 0;
+}
+
+void parse_options(int argc, char *argv[], struct nilfs_tune_options *opts)
+{
+	int c;
+	opts->flags = O_RDONLY;
+	opts->display = 0;
+	opts->mask = 0;
+	opts->force = 0;
+
+	while ((c = getopt(argc, argv, "flhi:L:m:U:")) != EOF) {
+		switch (c) {
+		case 'f':
+			opts->force = 1;
+			break;
+		case 'h':
+			nilfs_tune_usage();
+			exit(EXIT_SUCCESS);
+			break;
+		case 'i':
+			opts->c_interval = atol(optarg);
+			opts->mask |= NILFS_SB_COMMIT_INTERVAL;
+			opts->flags = O_RDWR;
+			break;
+		case 'L':
+			strncpy(opts->label, optarg, sizeof(opts->label));
+			opts->mask |= NILFS_SB_LABEL;
+			opts->flags = O_RDWR;
+			break;
+		case 'm':
+			opts->c_block_max = atol(optarg);
+			opts->mask |= NILFS_SB_BLOCK_MAX;
+			opts->flags = O_RDWR;
+			break;
+		case 'l':
+			opts->display = 1;
+			break;
+		case 'U':
+			if (parse_uuid(optarg, opts->uuid)) {
+				fprintf(stderr, "Invalid UUID format\n");
+				exit(EXIT_FAILURE);
+			}
+			opts->mask |= NILFS_SB_UUID;
+			opts->flags = O_RDWR;
+			break;
+		default:
+			nilfs_tune_usage();
+		}
+	}
+}
+
+#define MINUTE	(60)
+#define HOUR	(MINUTE * 60)
+#define DAY	(HOUR * 24)
+#define WEEK	(DAY * 7)
+#define MONTH	(DAY * 30)
+
+#define DIV_SECS(v, C)		\
+do {				\
+	if (secs > (C)) {	\
+		v = secs / C;	\
+		secs -= v * C;	\
+	} else {		\
+		v = 0;		\
+	}			\
+} while(0)
+
+#define FORMAT_VARIABLE(v) \
+do {				\
+	if (v##s) {		\
+		sprintf(tmp, "%s%d " #v "%s", buf[0] ? ", " : "", \
+			v##s, (v##s>1) ? "s" : ""); \
+		strcat(buf, tmp);	\
+	}			\
+} while(0)
+
+static const char *interval_string(unsigned int secs)
+{
+	static char buf[512], tmp[128];
+	int months, weeks, days, hours, minutes;
+
+	if (secs == 0)
+		return "none";
+
+	buf[0] = 0;
+	DIV_SECS(months, MONTH);
+	DIV_SECS(weeks, WEEK);
+	DIV_SECS(days, DAY);
+	DIV_SECS(hours, HOUR);
+	DIV_SECS(minutes, MINUTE);
+
+	FORMAT_VARIABLE(month);
+	FORMAT_VARIABLE(week);
+	FORMAT_VARIABLE(day);
+	FORMAT_VARIABLE(hour);
+	FORMAT_VARIABLE(minute);
+	FORMAT_VARIABLE(sec);
+
+	return buf;
+}
+
+static const char *user_string(uid_t uid)
+{
+	static char tmp[LOGIN_NAME_MAX];
+	static char buf[LOGIN_NAME_MAX + 8];
+	struct passwd *pwd;
+
+	strcpy(buf, "user ");
+
+	pwd = getpwuid(uid);
+	if (pwd)
+		strncpy(tmp, pwd->pw_name, sizeof(tmp));
+	else
+		strcpy(tmp, "unknown");
+	strcat(buf, tmp);
+	return buf;
+}
+
+static const char *group_string(gid_t gid)
+{
+	static char tmp[LOGIN_NAME_MAX];
+	static char buf[LOGIN_NAME_MAX + 8];
+	struct group *grp;
+
+	strcpy(buf, "group ");
+
+	grp = getgrgid(gid);
+	if (grp)
+		strncpy(tmp, grp->gr_name, sizeof(tmp));
+	else
+		strcpy(tmp, "unknown");
+	strcat(buf, tmp);
+	return buf;
+}
+
+static const char *uuid_string(unsigned char *uuid)
+{
+	static char buf[256];
+
+	sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+		"%02x%02x-%02x%02x%02x%02x%02x%02x", uuid[0], uuid[1],
+		uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
+		uuid[8], uuid[9], uuid[10], uuid[11], uuid[12],
+		uuid[13], uuid[14], uuid[15]);
+	return buf;
+}
+
+static const char *state_string(unsigned int state)
+{
+	static char buf[256];
+
+	if (state & NILFS_VALID_FS)
+		strcpy(buf, "valid");
+	else
+		strcpy(buf, "invalid or mounted");
+	if (state & NILFS_ERROR_FS)
+		strcat(buf, ",error");
+	if (state & NILFS_RESIZE_FS)
+		strcat(buf, ",resize");
+	return buf;
+}
+
+static const char *creator_os_string(unsigned int creator)
+{
+	static char buf[64];
+
+	switch(creator) {
+	case NILFS_OS_LINUX:
+		strcpy(buf, "Linux");
+		break;
+	default:
+		strcpy(buf, "Unknown");
+		break;
+	}
+
+	return buf;
+}
+
+static char *time_string(time_t t)
+{
+	return ctime(&t);
+}
+
+void show_nilfs_sb(struct nilfs_super_block *sbp)
+{
+	char label[sizeof(sbp->s_volume_name) + 1];
+	gid_t gid;
+	uid_t uid;
+
+	memset(label, 0, sizeof(label));
+	memcpy(label, sbp->s_volume_name, sizeof(sbp->s_volume_name));
+	if (!label[0])
+		strcpy(label, "<none>");
+
+	printf("Filesystem volume name:\t  %s\n", label);
+	printf("Filesystem UUID:\t  %s\n", uuid_string(sbp->s_uuid));
+	printf("Filesystem magic number:  0x%04x\n",
+	       le16_to_cpu(sbp->s_magic));
+	printf("Filesystem revision #:\t  %d.%d\n",
+	       le32_to_cpu(sbp->s_rev_level),
+	       le32_to_cpu(sbp->s_minor_rev_level));
+
+	/* sbp->s_flags is not used */
+
+	printf("Filesystem state:\t  %s\n",
+	       state_string(le16_to_cpu(sbp->s_state)));
+
+	/* sbp->s_errors is not used */
+
+	printf("Filesystem OS type:\t  %s\n",
+	       creator_os_string(le32_to_cpu(sbp->s_creator_os)));
+
+	printf("Block size:\t\t  %u\n",
+	       1 << (le32_to_cpu(sbp->s_log_block_size) + 10));
+
+	printf("Filesystem created:\t  %s",
+	       time_string(le64_to_cpu(sbp->s_ctime)));
+	printf("Last mount time:\t  %s",
+	       time_string(le64_to_cpu(sbp->s_mtime)));
+	printf("Last write time:\t  %s",
+	       time_string(le64_to_cpu(sbp->s_wtime)));
+	printf("Mount count:\t\t  %u\n", le16_to_cpu(sbp->s_mnt_count));
+	printf("Maximum mount count:\t  %u\n",
+	       le16_to_cpu(sbp->s_max_mnt_count));
+
+#if 0 /* filesystem check is not implemented yet */
+	{
+		time_t t;
+		unsigned int interval;
+
+		t = (time_t)le64_to_cpu(sbp->s_lastcheck);
+		printf("Last checked:\t\t  %s", ctime(&t));
+
+		interval = le32_to_cpu(sbp->s_checkinterval);
+		printf("Check interval:\t\t  %u (%s)\n", interval,
+		       interval_string(interval));
+
+		if(interval)
+			printf("Next check after:\t  %s",
+			       time_string(t+interval));
+	}
+#endif
+
+	uid = (uid_t)le16_to_cpu(sbp->s_def_resuid);
+	printf("Reserve blocks uid:\t  %u (%s)\n", uid, user_string(uid));
+	gid = (gid_t)le16_to_cpu(sbp->s_def_resgid);
+	printf("Reserve blocks gid:\t  %u (%s)\n", gid, group_string(gid));
+
+	printf("First inode:\t\t  %u\n", le32_to_cpu(sbp->s_first_ino));
+
+	printf("Inode size:\t\t  %u\n", le16_to_cpu(sbp->s_inode_size));
+	printf("DAT entry size:\t\t  %u\n", le16_to_cpu(sbp->s_dat_entry_size));
+	printf("Checkpoint size:\t  %u\n",
+	       le16_to_cpu(sbp->s_checkpoint_size));
+	printf("Segment usage size:\t  %u\n",
+	       le16_to_cpu(sbp->s_segment_usage_size));
+
+	printf("Number of segments:\t  %llu\n", le64_to_cpu(sbp->s_nsegments));
+	printf("Device size:\t\t  %llu\n", le64_to_cpu(sbp->s_dev_size));
+	printf("First data block:\t  %llu\n",
+	       le64_to_cpu(sbp->s_first_data_block));
+	printf("# of blocks per segment:  %u\n",
+	       le32_to_cpu(sbp->s_blocks_per_segment));
+	printf("Reserved segments %%:\t  %u\n",
+	       le32_to_cpu(sbp->s_r_segments_percentage));
+	printf("Last checkpoint #:\t  %llu\n", le64_to_cpu(sbp->s_last_cno));
+	printf("Last block address:\t  %llu\n", le64_to_cpu(sbp->s_last_pseg));
+	printf("Last sequence #:\t  %llu\n", le64_to_cpu(sbp->s_last_seq));
+	printf("Free blocks count:\t  %llu\n",
+	       le64_to_cpu(sbp->s_free_blocks_count));
+
+	printf("Commit interval:\t  %u\n", le32_to_cpu(sbp->s_c_interval));
+	printf("# of blks to create seg:  %u\n", le32_to_cpu(sbp->s_c_block_max));
+
+	printf("CRC seed:\t\t  0x%08x\n", le32_to_cpu(sbp->s_crc_seed));
+	printf("CRC check sum:\t\t  0x%08x\n", le32_to_cpu(sbp->s_sum));
+	printf("CRC check data size:\t  0x%08x\n", le32_to_cpu(sbp->s_bytes));
+}
+
+int modify_nilfs(char *device, struct nilfs_tune_options *opts)
+{
+	int devfd;
+	int ret = EXIT_SUCCESS;
+	struct nilfs_super_block *sbp;
+	__u64 features;
+
+	devfd = open(device, opts->flags);
+
+	if (devfd == -1) {
+		fprintf(stderr, "%s: cannot open NILFS\n", device);
+		ret = EXIT_FAILURE;
+		goto out;
+	}
+
+	sbp = nilfs_sb_read(devfd);
+	if (!sbp) {
+		fprintf(stderr, "%s: cannot open NILFS\n", device);
+		ret = EXIT_FAILURE;
+		goto close_fd;
+	}
+
+	features = le64_to_cpu(sbp->s_feature_incompat);
+	if (features & ~NILFS_FEATURE_INCOMPAT_SUPP)
+		fprintf(stderr, "Warning: %s: unknown incompatible "
+			"features: 0x%llx\n", device, features);
+
+	features = le64_to_cpu(sbp->s_feature_compat_ro);
+	if (opts->flags == O_RDWR &&
+	    (features & ~NILFS_FEATURE_COMPAT_RO_SUPP))
+		fprintf(stderr, "Warning: %s: unknown read-only compatible "
+			"features: 0x%llx\n", device, features);
+
+	if (opts->mask & NILFS_SB_LABEL)
+		memcpy(sbp->s_volume_name, opts->label,
+		       sizeof(opts->label));
+	if (opts->mask & NILFS_SB_UUID)
+		memcpy(sbp->s_uuid, opts->uuid, sizeof(opts->uuid));
+	if (opts->mask & NILFS_SB_COMMIT_INTERVAL)
+		sbp->s_c_interval = cpu_to_le32(opts->c_interval);
+	if (opts->mask & NILFS_SB_BLOCK_MAX)
+		sbp->s_c_block_max = cpu_to_le32(opts->c_block_max);
+
+	if (opts->mask)
+		nilfs_sb_write(devfd, sbp, opts->mask);
+
+	if (opts->display)
+		show_nilfs_sb(sbp);
+
+	free(sbp);
+
+ close_fd:
+	close(devfd);
+ out:
+	return ret;
+}
+
+/* Code borrowed from nilfs2-util/sbin/mkfs/mkfs.c */
+static int check_mount(const char *device)
+{
+	FILE *fp;
+	char line[LINE_BUFFER_SIZE];
+
+	fp = fopen(MOUNTS, "r");
+	if (fp == NULL) {
+		fprintf(stderr, "Error: cannot open %s!", MOUNTS);
+		return 1;
+	}
+
+	while (fgets(line, LINE_BUFFER_SIZE, fp) != NULL) {
+		if (strncmp(strtok(line, " "), device, strlen(device)) == 0) {
+			fclose(fp);
+			return 1;
+		}
+	}
+	fclose(fp);
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	struct nilfs_tune_options opts;
+	char *device;
+
+	printf("nilfs-tune %s\n", VERSION);
+	if (argc < 2) {
+		nilfs_tune_usage();
+		exit(EXIT_SUCCESS);
+	}
+
+	parse_options(argc, argv, &opts);
+
+	device = argv[argc-1];
+
+	if (!device) {
+		nilfs_tune_usage();
+		exit(EXIT_FAILURE);
+	}
+
+	if (!opts.force && opts.flags == O_RDWR && check_mount(device)) {
+		fprintf(stderr, "Warning: %s is currently mounted.\n"
+			"Running nilfs-tune on a mounted file system "
+			"may cause SEVERE damage.\n"
+			"You can force to modify file system by "
+			"\"-f\" option.\n",
+			device);
+		exit(EXIT_SUCCESS);
+	}
+
+	return modify_nilfs(device, &opts);
+}
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux BTRFS]     [Linux CIFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux