All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <quwenruo@cn.fujitsu.com>
To: <linux-btrfs@vger.kernel.org>
Subject: [PATCH v2 12/13] btrfs-progs: Add offline type for btrfs property.
Date: Mon, 11 May 2015 16:08:53 +0800	[thread overview]
Message-ID: <1431331734-11714-13-git-send-email-quwenruo@cn.fujitsu.com> (raw)
In-Reply-To: <1431331734-11714-1-git-send-email-quwenruo@cn.fujitsu.com>

Add new offline type for btrfs property, it has two members:
1) fsid: Set/get fsid of an *OFFLINE* btrfs.
2) chunk_tree_uuid: Set/get chunk tree uuid of an *OFFLINE* btrfs

The new type is added to distinguish these dangerous offline operation
from the normal online operations.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
v2:
  Newly introduced.
---
 cmds-property.c |   5 ++-
 props.c         | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 props.h         |   1 +
 3 files changed, 128 insertions(+), 1 deletion(-)

diff --git a/cmds-property.c b/cmds-property.c
index 6501338..6c699db 100644
--- a/cmds-property.c
+++ b/cmds-property.c
@@ -41,7 +41,7 @@ static const char * const cmd_get_usage[] = {
 	"an inode or a device. The '-t <type>' option can be used to explicitly",
 	"specify what type of object you meant. This is only needed when a",
 	"property could be set for more then one object type. Possible types",
-	"are s[ubvol], f[ilesystem], i[node] and d[evice].",
+	"are s[ubvol], f[ilesystem], i[node], d[evice] and o[ffline].",
 	NULL
 };
 
@@ -360,6 +360,9 @@ static void parse_args(int argc, char **argv,
 		} else if (!strcmp(type_str, "d") ||
 			   !strcmp(type_str, "device")) {
 			*types = prop_object_dev;
+		} else if (!strcmp(type_str, "o") ||
+			   !strcmp(type_str, "offline")) {
+			*types = prop_object_offline;
 		} else {
 			fprintf(stderr, "ERROR: invalid object type.\n");
 			usage(usage_str);
diff --git a/props.c b/props.c
index 9b2117c..73537bd 100644
--- a/props.c
+++ b/props.c
@@ -451,6 +451,125 @@ out:
 	return ret;
 }
 
+/* Will check if it is a block device/softlink/regular file, or mounted */
+static int check_offline(const char *device)
+{
+	struct stat statbuf;
+	int ret = 0;
+
+	ret = stat(device, &statbuf);
+	if (ret < 0) {
+		fprintf(stderr, "Failed to check status for %s: %s\n",
+			device, strerror(errno));
+		ret = -errno;
+		goto out;
+	}
+	if (!(S_ISBLK(statbuf.st_mode) || S_ISREG(statbuf.st_mode) ||
+	      S_ISLNK(statbuf.st_mode))) {
+		fprintf(stderr,
+			"%s is not a regular/device file containing btrfs\n",
+			device);
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = check_mounted(device);
+	if (ret < 0) {
+		fprintf(stderr, "Could not check mount status: %s\n",
+			strerror(-ret));
+	} else if (ret > 0) {
+		fprintf(stderr, "%s is mounted\n", device);
+		ret = -EINVAL;
+	}
+out:
+	return ret;
+}
+
+static int prop_offline_uuid(enum prop_object_type type,
+			     const char *object,
+			     const char *name,
+			     const char *value)
+{
+	struct btrfs_fs_info *fs_info;
+	enum btrfs_open_ctree_flags ctree_flags = 0;
+	char *uuid_name = NULL;
+	int is_fsid;
+	int ret = 0;
+
+	ret = check_offline(object);
+	if (ret < 0)
+		goto out;
+
+	if (!strcmp(name, "fsid")) {
+		is_fsid = 1;
+		uuid_name = "fsid";
+	} else {
+		is_fsid = 0;
+		uuid_name = "chunk_tree_uuid";
+	}
+
+	if (value) {
+		uuid_t tmp;
+		char fsid[BTRFS_UUID_UNPARSED_SIZE];
+
+		ctree_flags |= OPEN_CTREE_WRITES;
+		if (is_fsid)
+			ctree_flags |= OPEN_CTREE_IGNORE_FSID;
+		else
+			ctree_flags |= OPEN_CTREE_IGNORE_CHUNK_TREE_ID;
+
+		ret = uuid_parse(value, tmp);
+		if (ret < 0) {
+			fprintf(stderr, "could not parse UUID: %s\n", value);
+			goto out;
+		}
+
+		/*
+		 * Copy value to fsid, to avoid warning about discarding
+		 * 'const' qualifier.
+		 * The root cause is from blkid library used by
+		 * test_uuid_unique, no good fix in btrfs.
+		 */
+		strcpy(fsid, value);
+
+		if (!test_uuid_unique(fsid)) {
+			fprintf(stderr, "non-unique UUID: %s\n", fsid);
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
+	fs_info = open_ctree_fs_info(object, 0, 0, ctree_flags);
+	if (!fs_info) {
+		ret = -EIO;
+		goto out;
+	}
+
+	/* For get, we just use fsid from fs_info */
+	if (!value) {
+		char buf[BTRFS_UUID_UNPARSED_SIZE] = {'\0'};
+
+		uuid_unparse(fs_info->fsid, buf);
+		fprintf(stdout, "%s=%s\n", uuid_name, buf);
+		goto close_ctree;
+	}
+
+	/* Here, we are going to change uuid*/
+	if (is_fsid)
+		ret = change_uuid(fs_info, value, NULL);
+	else
+		ret = change_uuid(fs_info, NULL, value);
+	if (ret < 0)
+		fprintf(stderr, "Failed to change %s: %s\n",
+			uuid_name, strerror(-ret));
+	else
+		printf("%s changed to %s\n", uuid_name, value);
+
+close_ctree:
+	close_ctree(fs_info->tree_root);
+out:
+	return ret;
+}
+
 const struct prop_handler prop_handlers[] = {
 	{"ro", "Set/get read-only flag of subvolume.", 0, prop_object_subvol,
 	 prop_read_only},
@@ -458,5 +577,9 @@ const struct prop_handler prop_handlers[] = {
 	 prop_object_dev | prop_object_root, prop_label},
 	{"compression", "Set/get compression for a file or directory", 0,
 	 prop_object_inode, prop_compression},
+	{"fsid", "Set/get fsid of a offline filesystem", 0,
+	 prop_object_offline, prop_offline_uuid},
+	{"chunk_tree_uuid", "Set/get fsid of a offline filesystem", 0,
+	 prop_object_offline, prop_offline_uuid},
 	{0, 0, 0, 0, 0}
 };
diff --git a/props.h b/props.h
index a43cb25..05c7761 100644
--- a/props.h
+++ b/props.h
@@ -22,6 +22,7 @@ enum prop_object_type {
 	prop_object_root	= (1 << 1),
 	prop_object_subvol	= (1 << 2),
 	prop_object_inode	= (1 << 3),
+	prop_object_offline	= (1 << 4),
 	__prop_object_max,
 };
 
-- 
2.4.0


  parent reply	other threads:[~2015-05-11  8:09 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-11  8:08 [PATCH v2 00/13] Introduce offline fsid/chunk tree uuid change for btrfstune Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 01/13] btrfs-progs: Add CHANGIND_FSID and CHANGING_CHUNK_TREE_ID super flags Qu Wenruo
2015-05-13 13:57   ` David Sterba
2015-05-11  8:08 ` [PATCH v2 02/13] btrfs-progs: Use unified function to implement print_readable_*_flag() function Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 03/13] btrfs-progs: Make btrfs-show-super print human readable flag for super flags Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 04/13] btrfs-progs: Add open_ctree check for uuid changing Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 05/13] btrfs-progs: Export write_tree_block() Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 06/13] btrfs-progs: Introduce change_header_uuid() function Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 07/13] btrfs-progs: Introduce change_extents_uuid() function Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 08/13] btrfs-progs: Introduce change_device_uuid() function Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 09/13] btrfs-progs: Introduce change_devices_uuid() function Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 10/13] btrfs-progs: Introduce change_id_prepare() and change_id_done() functions Qu Wenruo
2015-05-11  8:08 ` [PATCH v2 11/13] btrfs-progs: Introduce change_uuid() function Qu Wenruo
2015-05-11  8:08 ` Qu Wenruo [this message]
2015-05-11  8:08 ` [PATCH v2 13/13] btrfs-progs: Update Doc for btrfs-property Qu Wenruo
2015-05-13 13:56 ` [PATCH v2 00/13] Introduce offline fsid/chunk tree uuid change for btrfstune David Sterba
2015-05-13 16:03 ` David Sterba
2015-05-14  0:33   ` Qu Wenruo
2015-05-14 13:32     ` David Sterba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1431331734-11714-13-git-send-email-quwenruo@cn.fujitsu.com \
    --to=quwenruo@cn.fujitsu.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.