Пример #1
0
int main(int ac, char **av)
{
	struct btrfs_root *root;
	struct btrfs_trans_handle *trans;
	int ret;

	set_argv0(av);
	if (check_argc_exact(ac, 2))
		print_usage();

	radix_tree_init();

	if((ret = check_mounted(av[1])) < 0) {
		fprintf(stderr, "Could not check mount status: %s\n", strerror(-ret));
		goto out;
	} else if(ret) {
		fprintf(stderr, "%s is currently mounted. Aborting.\n", av[1]);
		ret = -EBUSY;
		goto out;
	}

	root = open_ctree(av[1], 0, OPEN_CTREE_WRITES);

	if (root == NULL)
		return 1;

	trans = btrfs_start_transaction(root, 1);
	btrfs_set_super_log_root(root->fs_info->super_copy, 0);
	btrfs_set_super_log_root_level(root->fs_info->super_copy, 0);
	btrfs_commit_transaction(trans, root);
	close_ctree(root);
out:
	return !!ret;
}
int main(int argc, char **argv)
{
	int c;
	unsigned long checksum = 0;
	char *str;
	char *buf;
	int length = 10;
	u64 seed = 0;
	int loop = 0;
	int i;

	while ((c = getopt(argc, argv, "l:c:s:h")) != -1) {
		switch (c) {
		case 'l':
			length = atol(optarg);
			break;
		case 'c':
			sscanf(optarg, "%li", &checksum);
			loop = 1;
			break;
		case 's':
			seed = atoll(optarg);
			break;
		case 'h':
			print_usage(1);
		case '?':
			print_usage(255);
		}
	}

	set_argv0(argv);
	str = argv[optind];

	if (!loop) {
		if (check_argc_exact(argc - optind, 1))
			print_usage(255);

		printf("%12u - %s\n", crc32c(~1, str, strlen(str)), str);
		return 0;
	}
	if (check_argc_exact(argc - optind, 0))
		print_usage(255);

	buf = malloc(length);
	if (!buf)
		return -ENOMEM;
	if (seed)
		init_rand_seed(seed);

	while (1) {
		for (i = 0; i < length; i++)
			buf[i] = rand_range(94) + 33;
		if (crc32c(~1, buf, length) == checksum)
			printf("%12lu - %.*s\n", checksum, length, buf);
	}

	return 0;
}
Пример #3
0
int main(int argc, char **argv)
{
	char *path;
	int fd;
	int ret;
	u64 flags = 0;
	char *dir = "html";
	DIR *dirstream = NULL;

	while (1) {
		int c = getopt(argc, argv, "cmso:h");
		if (c < 0)
			break;
		switch (c) {
		case 'c':
			use_color = 1;
			break;
		case 'd':
			flags |= BTRFS_BLOCK_GROUP_DATA;
			break;
		case 'm':
			flags |= BTRFS_BLOCK_GROUP_METADATA;
			break;
		case 's':
			flags |= BTRFS_BLOCK_GROUP_SYSTEM;
			break;
		case 'o':
			dir = optarg;
			break;
		case 'h':
		default:
			fragments_usage();
		}
	}

	set_argv0(argv);
	if (check_argc_min(argc - optind, 1))
		fragments_usage();

	path = argv[optind++];

	fd = btrfs_open_dir(path, &dirstream, 1);
	if (fd < 0)
		exit(1);

	if (flags == 0)
		flags = BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA;

	ret = list_fragments(fd, flags, dir);
	close_file_or_dir(fd, dirstream);
	if (ret)
		exit(1);

	exit(0);
}
Пример #4
0
int main(int argc, char **argv)
{
	struct btrfs_root *root;
	int dev_fd;
	int opt;
	int ret;

	while ((opt = getopt(argc, argv, "l:o:g:")) != -1) {
		switch(opt) {
			case 'o':
				search_objectid = arg_strtou64(optarg);
				break;
			case 'g':
				search_generation = arg_strtou64(optarg);
				break;
			case 'l':
				search_level = arg_strtou64(optarg);
				break;
			default:
				usage();
				exit(1);
		}
	}

	set_argv0(argv);
	argc = argc - optind;
	if (check_argc_min(argc, 1)) {
		usage();
		exit(1);
	}

	dev_fd = open(argv[optind], O_RDONLY);
	if (dev_fd < 0) {
		fprintf(stderr, "Failed to open device %s\n", argv[optind]);
		exit(1);
	}

	root = open_ctree_broken(dev_fd, argv[optind]);
	close(dev_fd);

	if (!root) {
		fprintf(stderr, "Open ctree failed\n");
		exit(1);
	}

	if (search_generation == 0)
		search_generation = btrfs_super_generation(root->fs_info->super_copy);

	csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
	ret = find_root(root);
	close_ctree(root);
	return ret;
}
Пример #5
0
int main(int argc, char **argv)
{

	int ret;

	set_argv0(argv);

	warning(
"\nthe tool has been deprecated, please use 'btrfs inspect-internal dump-super' instead\n");

	if (argc > 1 && !strcmp(argv[1], "--help"))
		usage(cmd_inspect_dump_super_usage);

	ret = cmd_inspect_dump_super(argc, argv);

	return ret;
}
Пример #6
0
int main(int ac, char **av)
{
	struct btrfs_root *root;
	struct btrfs_trans_handle *trans;
	struct btrfs_super_block *sb;
	int ret;

	set_argv0(av);
	if (check_argc_exact(ac, 2))
		print_usage();

	radix_tree_init();

	printf("WARNING: this utility is deprecated, please use 'btrfs rescue zero-log'\n\n");

	if ((ret = check_mounted(av[1])) < 0) {
		fprintf(stderr, "ERROR: could not check mount status: %s\n", strerror(-ret));
		goto out;
	} else if (ret) {
		fprintf(stderr, "ERROR: %s is currently mounted\n", av[1]);
		ret = -EBUSY;
		goto out;
	}

	root = open_ctree(av[1], 0, OPEN_CTREE_WRITES | OPEN_CTREE_PARTIAL);
	if (!root) {
		fprintf(stderr, "ERROR: cannot open ctree\n");
		return 1;
	}

	sb = root->fs_info->super_copy;
	printf("Clearing log on %s, previous log_root %llu, level %u\n",
			av[1],
			(unsigned long long)btrfs_super_log_root(sb),
			(unsigned)btrfs_super_log_root_level(sb));
	trans = btrfs_start_transaction(root, 1);
	btrfs_set_super_log_root(root->fs_info->super_copy, 0);
	btrfs_set_super_log_root_level(root->fs_info->super_copy, 0);
	btrfs_commit_transaction(trans, root);
	close_ctree(root);
out:
	return !!ret;
}
Пример #7
0
int main(int argc, char* argv[])
{
  struct timeval tv;
  int lastarg;
  
  gettimeofday(&tv, 0);
  srandom(tv.tv_usec ^ tv.tv_sec);
  
  set_argv0(argv[0]);
  lastarg = parse_args(argc, argv);

  if(do_show_usage)
    usage(0, 0);

  argc -= lastarg;
  argv += lastarg;
  if(argc < cli_args_min)
    usage(1, "Too few command-line arguments");
  if(cli_args_max >= cli_args_min && argc > cli_args_max)
    usage(1, "Too many command-line arguments");
  
  return cli_main(argc, argv);
}
Пример #8
0
int main(int argc, char **argv)
{
	int opt;
	int all = 0;
	int full = 0;
	int force = 0;
	char *filename;
	int fd = -1;
	int i;
	u64 arg;
	u64 sb_bytenr = btrfs_sb_offset(0);

	while ((opt = getopt(argc, argv, "fFai:s:")) != -1) {
		switch (opt) {
		case 'i':
			arg = arg_strtou64(optarg);
			if (arg >= BTRFS_SUPER_MIRROR_MAX) {
				fprintf(stderr,
					"Illegal super_mirror %llu\n",
					arg);
				print_usage();
				exit(1);
			}
			sb_bytenr = btrfs_sb_offset(arg);
			break;

		case 'a':
			all = 1;
			break;
		case 'f':
			full = 1;
			break;
		case 'F':
			force = 1;
			break;
		case 's':
			sb_bytenr = arg_strtou64(optarg);
			all = 0;
			break;
		default:
			print_usage();
			exit(1);
		}
	}

	set_argv0(argv);
	if (check_argc_min(argc - optind, 1)) {
		print_usage();
		exit(1);
	}

	for (i = optind; i < argc; i++) {
		filename = argv[i];
		fd = open(filename, O_RDONLY, 0666);
		if (fd < 0) {
			fprintf(stderr, "Could not open %s\n", filename);
			exit(1);
		}

		if (all) {
			int idx;
			for (idx = 0; idx < BTRFS_SUPER_MIRROR_MAX; idx++) {
				sb_bytenr = btrfs_sb_offset(idx);
				if (load_and_dump_sb(filename, fd,
						sb_bytenr, full, force)) {
					close(fd);
					exit(1);
				}

				putchar('\n');
			}
		} else {
			load_and_dump_sb(filename, fd, sb_bytenr, full, force);
			putchar('\n');
		}
		close(fd);
	}

	exit(0);
}
Пример #9
0
int main(int ac, char **av)
{
    struct btrfs_root *root;
    struct btrfs_fs_info *info;
    struct btrfs_path path;
    struct btrfs_key key;
    struct btrfs_root_item ri;
    struct extent_buffer *leaf;
    struct btrfs_disk_key disk_key;
    struct btrfs_key found_key;
    char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
    int ret;
    int slot;
    int extent_only = 0;
    int device_only = 0;
    int uuid_tree_only = 0;
    int roots_only = 0;
    int root_backups = 0;
    u64 block_only = 0;
    struct btrfs_root *tree_root_scan;
    u64 tree_id = 0;

    radix_tree_init();

    while(1) {
        int c;
        static const struct option long_options[] = {
            { "help", no_argument, NULL, GETOPT_VAL_HELP},
            { NULL, 0, NULL, 0 }
        };

        c = getopt_long(ac, av, "deb:rRut:", long_options, NULL);
        if (c < 0)
            break;
        switch(c) {
        case 'e':
            extent_only = 1;
            break;
        case 'd':
            device_only = 1;
            break;
        case 'r':
            roots_only = 1;
            break;
        case 'u':
            uuid_tree_only = 1;
            break;
        case 'R':
            roots_only = 1;
            root_backups = 1;
            break;
        case 'b':
            block_only = arg_strtou64(optarg);
            break;
        case 't':
            tree_id = arg_strtou64(optarg);
            break;
        case GETOPT_VAL_HELP:
        default:
            print_usage(c != GETOPT_VAL_HELP);
        }
    }
    set_argv0(av);
    ac = ac - optind;
    if (check_argc_exact(ac, 1))
        print_usage(1);

    ret = check_arg_type(av[optind]);
    if (ret != BTRFS_ARG_BLKDEV && ret != BTRFS_ARG_REG) {
        fprintf(stderr, "'%s' is not a block device or regular file\n",
                av[optind]);
        exit(1);
    }

    info = open_ctree_fs_info(av[optind], 0, 0, OPEN_CTREE_PARTIAL);
    if (!info) {
        fprintf(stderr, "unable to open %s\n", av[optind]);
        exit(1);
    }

    root = info->fs_root;
    if (!root) {
        fprintf(stderr, "unable to open %s\n", av[optind]);
        exit(1);
    }

    if (block_only) {
        leaf = read_tree_block(root,
                               block_only,
                               root->leafsize, 0);

        if (extent_buffer_uptodate(leaf) &&
                btrfs_header_level(leaf) != 0) {
            free_extent_buffer(leaf);
            leaf = NULL;
        }

        if (!leaf) {
            leaf = read_tree_block(root,
                                   block_only,
                                   root->nodesize, 0);
        }
        if (!extent_buffer_uptodate(leaf)) {
            fprintf(stderr, "failed to read %llu\n",
                    (unsigned long long)block_only);
            goto close_root;
        }
        btrfs_print_tree(root, leaf, 0);
        free_extent_buffer(leaf);
        goto close_root;
    }

    if (!(extent_only || uuid_tree_only || tree_id)) {
        if (roots_only) {
            printf("root tree: %llu level %d\n",
                   (unsigned long long)info->tree_root->node->start,
                   btrfs_header_level(info->tree_root->node));
            printf("chunk tree: %llu level %d\n",
                   (unsigned long long)info->chunk_root->node->start,
                   btrfs_header_level(info->chunk_root->node));
        } else {
            if (info->tree_root->node) {
                printf("root tree\n");
                btrfs_print_tree(info->tree_root,
                                 info->tree_root->node, 1);
            }

            if (info->chunk_root->node) {
                printf("chunk tree\n");
                btrfs_print_tree(info->chunk_root,
                                 info->chunk_root->node, 1);
            }
        }
    }
    tree_root_scan = info->tree_root;

    btrfs_init_path(&path);
again:
    if (!extent_buffer_uptodate(tree_root_scan->node))
        goto no_node;

    /*
     * Tree's that are not pointed by the tree of tree roots
     */
    if (tree_id && tree_id == BTRFS_ROOT_TREE_OBJECTID) {
        if (!info->tree_root->node) {
            error("cannot print root tree, invalid pointer");
            goto no_node;
        }
        printf("root tree\n");
        btrfs_print_tree(info->tree_root, info->tree_root->node, 1);
        goto no_node;
    }

    if (tree_id && tree_id == BTRFS_CHUNK_TREE_OBJECTID) {
        if (!info->chunk_root->node) {
            error("cannot print chunk tree, invalid pointer");
            goto no_node;
        }
        printf("chunk tree\n");
        btrfs_print_tree(info->chunk_root, info->chunk_root->node, 1);
        goto no_node;
    }

    key.offset = 0;
    key.objectid = 0;
    btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
    ret = btrfs_search_slot(NULL, tree_root_scan, &key, &path, 0, 0);
    BUG_ON(ret < 0);
    while(1) {
        leaf = path.nodes[0];
        slot = path.slots[0];
        if (slot >= btrfs_header_nritems(leaf)) {
            ret = btrfs_next_leaf(tree_root_scan, &path);
            if (ret != 0)
                break;
            leaf = path.nodes[0];
            slot = path.slots[0];
        }
        btrfs_item_key(leaf, &disk_key, path.slots[0]);
        btrfs_disk_key_to_cpu(&found_key, &disk_key);
        if (btrfs_key_type(&found_key) == BTRFS_ROOT_ITEM_KEY) {
            unsigned long offset;
            struct extent_buffer *buf;
            int skip = extent_only | device_only | uuid_tree_only;

            offset = btrfs_item_ptr_offset(leaf, slot);
            read_extent_buffer(leaf, &ri, offset, sizeof(ri));
            buf = read_tree_block(tree_root_scan,
                                  btrfs_root_bytenr(&ri),
                                  btrfs_level_size(tree_root_scan,
                                                   btrfs_root_level(&ri)),
                                  0);
            if (!extent_buffer_uptodate(buf))
                goto next;
            if (tree_id && found_key.objectid != tree_id) {
                free_extent_buffer(buf);
                goto next;
            }

            switch(found_key.objectid) {
            case BTRFS_ROOT_TREE_OBJECTID:
                if (!skip)
                    printf("root");
                break;
            case BTRFS_EXTENT_TREE_OBJECTID:
                if (!device_only && !uuid_tree_only)
                    skip = 0;
                if (!skip)
                    printf("extent");
                break;
            case BTRFS_CHUNK_TREE_OBJECTID:
                if (!skip) {
                    printf("chunk");
                }
                break;
            case BTRFS_DEV_TREE_OBJECTID:
                if (!uuid_tree_only)
                    skip = 0;
                if (!skip)
                    printf("device");
                break;
            case BTRFS_FS_TREE_OBJECTID:
                if (!skip) {
                    printf("fs");
                }
                break;
            case BTRFS_ROOT_TREE_DIR_OBJECTID:
                skip = 0;
                printf("directory");
                break;
            case BTRFS_CSUM_TREE_OBJECTID:
                if (!skip) {
                    printf("checksum");
                }
                break;
            case BTRFS_ORPHAN_OBJECTID:
                if (!skip) {
                    printf("orphan");
                }
                break;
            case BTRFS_TREE_LOG_OBJECTID:
                if (!skip) {
                    printf("log");
                }
                break;
            case BTRFS_TREE_LOG_FIXUP_OBJECTID:
                if (!skip) {
                    printf("log fixup");
                }
                break;
            case BTRFS_TREE_RELOC_OBJECTID:
                if (!skip) {
                    printf("reloc");
                }
                break;
            case BTRFS_DATA_RELOC_TREE_OBJECTID:
                if (!skip) {
                    printf("data reloc");
                }
                break;
            case BTRFS_EXTENT_CSUM_OBJECTID:
                if (!skip) {
                    printf("extent checksum");
                }
                break;
            case BTRFS_QUOTA_TREE_OBJECTID:
                if (!skip) {
                    printf("quota");
                }
                break;
            case BTRFS_UUID_TREE_OBJECTID:
                if (!extent_only && !device_only)
                    skip = 0;
                if (!skip)
                    printf("uuid");
                break;
            case BTRFS_FREE_SPACE_TREE_OBJECTID:
                if (!skip)
                    printf("free space");
                break;
            case BTRFS_MULTIPLE_OBJECTIDS:
                if (!skip) {
                    printf("multiple");
                }
                break;
            default:
                if (!skip) {
                    printf("file");
                }
            }
            if (extent_only && !skip) {
                print_extents(tree_root_scan, buf);
            } else if (!skip) {
                printf(" tree ");
                btrfs_print_key(&disk_key);
                if (roots_only) {
                    printf(" %llu level %d\n",
                           (unsigned long long)buf->start,
                           btrfs_header_level(buf));
                } else {
                    printf(" \n");
                    btrfs_print_tree(tree_root_scan, buf, 1);
                }
            }
            free_extent_buffer(buf);
        }
next:
        path.slots[0]++;
    }
no_node:
    btrfs_release_path(&path);

    if (tree_root_scan == info->tree_root &&
            info->log_root_tree) {
        tree_root_scan = info->log_root_tree;
        goto again;
    }

    if (extent_only || device_only || uuid_tree_only)
        goto close_root;

    if (root_backups)
        print_old_roots(info->super_copy);

    printf("total bytes %llu\n",
           (unsigned long long)btrfs_super_total_bytes(info->super_copy));
    printf("bytes used %llu\n",
           (unsigned long long)btrfs_super_bytes_used(info->super_copy));
    uuidbuf[BTRFS_UUID_UNPARSED_SIZE - 1] = '\0';
    uuid_unparse(info->super_copy->fsid, uuidbuf);
    printf("uuid %s\n", uuidbuf);
    printf("%s\n", PACKAGE_STRING);
close_root:
    ret = close_ctree(root);
    btrfs_close_all_devices();
    return ret;
}
Пример #10
0
int main(int ac, char **av)
{
	struct cache_tree root_cache;
	struct btrfs_root *root;
	char *dev;
	char *output_file = NULL;
	u64 copy = 0;
	u64 logical = 0;
	u64 bytes = 0;
	u64 cur_logical = 0;
	u64 cur_len = 0;
	int out_fd = -1;
	int found = 0;
	int ret = 0;

	while(1) {
		int c;
		static const struct option long_options[] = {
			/* { "byte-count", 1, NULL, 'b' }, */
			{ "logical", required_argument, NULL, 'l' },
			{ "copy", required_argument, NULL, 'c' },
			{ "output", required_argument, NULL, 'o' },
			{ "bytes", required_argument, NULL, 'b' },
			{ NULL, 0, NULL, 0}
		};

		c = getopt_long(ac, av, "l:c:o:b:", long_options, NULL);
		if (c < 0)
			break;
		switch(c) {
			case 'l':
				logical = arg_strtou64(optarg);
				break;
			case 'c':
				copy = arg_strtou64(optarg);
				break;
			case 'b':
				bytes = arg_strtou64(optarg);
				break;
			case 'o':
				output_file = strdup(optarg);
				break;
			default:
				print_usage();
		}
	}
	set_argv0(av);
	ac = ac - optind;
	if (check_argc_min(ac, 1))
		print_usage();
	if (logical == 0)
		print_usage();

	dev = av[optind];

	radix_tree_init();
	cache_tree_init(&root_cache);

	root = open_ctree(dev, 0, 0);
	if (!root) {
		fprintf(stderr, "Open ctree failed\n");
		exit(1);
	}

	info_file = stdout;
	if (output_file) {
		if (strcmp(output_file, "-") == 0) {
			out_fd = 1;
			info_file = stderr;
		} else {
			out_fd = open(output_file, O_RDWR | O_CREAT, 0600);
			if (out_fd < 0)
				goto close;
			ret = ftruncate(out_fd, 0);
			if (ret) {
				ret = 1;
				close(out_fd);
				goto close;
			}
			info_file = stdout;
		}
	}

	if (bytes == 0)
		bytes = root->nodesize;
	cur_logical = logical;
	cur_len = bytes;

	/* First find the nearest extent */
	ret = map_one_extent(root->fs_info, &cur_logical, &cur_len, 0);
	if (ret < 0) {
		fprintf(stderr, "Failed to find extent at [%llu,%llu): %s\n",
			cur_logical, cur_logical + cur_len, strerror(-ret));
		goto out_close_fd;
	}
	/*
	 * Normally, search backward should be OK, but for special case like
	 * given logical is quite small where no extents are before it,
	 * we need to search forward.
	 */
	if (ret > 0) {
		ret = map_one_extent(root->fs_info, &cur_logical, &cur_len, 1);
		if (ret < 0) {
			fprintf(stderr,
				"Failed to find extent at [%llu,%llu): %s\n",
				cur_logical, cur_logical + cur_len,
				strerror(-ret));
			goto out_close_fd;
		}
		if (ret > 0) {
			fprintf(stderr,
				"Failed to find any extent at [%llu,%llu)\n",
				cur_logical, cur_logical + cur_len);
			goto out_close_fd;
		}
	}

	while (cur_logical + cur_len >= logical && cur_logical < logical +
	       bytes) {
		u64 real_logical;
		u64 real_len;

		found = 1;
		ret = map_one_extent(root->fs_info, &cur_logical, &cur_len, 1);
		if (ret < 0)
			goto out_close_fd;
		if (ret > 0)
			break;
		real_logical = max(logical, cur_logical);
		real_len = min(logical + bytes, cur_logical + cur_len) -
			   real_logical;

		ret = print_mapping_info(root->fs_info, real_logical, real_len);
		if (ret < 0)
			goto out_close_fd;
		if (output_file && out_fd != -1) {
			ret = write_extent_content(root->fs_info, out_fd,
					real_logical, real_len, copy);
			if (ret < 0)
				goto out_close_fd;
		}

		cur_logical += cur_len;
	}

	if (!found) {
		fprintf(stderr, "No extent found at range [%llu,%llu)\n",
			logical, logical + bytes);
	}
out_close_fd:
	if (output_file && out_fd != 1)
		close(out_fd);
close:
	close_ctree(root);
	if (ret < 0)
		ret = 1;
	return ret;
}
Пример #11
0
int main(int argc, char *argv[])
{
	struct btrfs_root *root;
	unsigned ctree_flags = OPEN_CTREE_WRITES;
	int success = 0;
	int total = 0;
	int seeding_flag = 0;
	u64 seeding_value = 0;
	int random_fsid = 0;
	char *new_fsid_str = NULL;
	int ret;
	u64 super_flags = 0;

	while(1) {
		static const struct option long_options[] = {
			{ "help", no_argument, NULL, GETOPT_VAL_HELP},
			{ NULL, 0, NULL, 0 }
		};
		int c = getopt_long(argc, argv, "S:rxfuU:n", long_options, NULL);

		if (c < 0)
			break;
		switch(c) {
		case 'S':
			seeding_flag = 1;
			seeding_value = arg_strtou64(optarg);
			break;
		case 'r':
			super_flags |= BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF;
			break;
		case 'x':
			super_flags |= BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA;
			break;
		case 'n':
			super_flags |= BTRFS_FEATURE_INCOMPAT_NO_HOLES;
			break;
		case 'f':
			force = 1;
			break;
		case 'U':
			ctree_flags |= OPEN_CTREE_IGNORE_FSID_MISMATCH;
			new_fsid_str = optarg;
			break;
		case 'u':
			ctree_flags |= OPEN_CTREE_IGNORE_FSID_MISMATCH;
			random_fsid = 1;
			break;
		case GETOPT_VAL_HELP:
		default:
			print_usage();
			return c != GETOPT_VAL_HELP;
		}
	}

	set_argv0(argv);
	device = argv[optind];
	if (check_argc_exact(argc - optind, 1)) {
		print_usage();
		return 1;
	}

	if (random_fsid && new_fsid_str) {
		error("random fsid can't be used with specified fsid");
		return 1;
	}
	if (!super_flags && !seeding_flag && !(random_fsid || new_fsid_str)) {
		error("at least one option should be specified");
		print_usage();
		return 1;
	}

	if (new_fsid_str) {
		uuid_t tmp;

		ret = uuid_parse(new_fsid_str, tmp);
		if (ret < 0) {
			error("could not parse UUID: %s", new_fsid_str);
			return 1;
		}
		if (!test_uuid_unique(new_fsid_str)) {
			error("fsid %s is not unique", new_fsid_str);
			return 1;
		}
	}

	ret = check_mounted(device);
	if (ret < 0) {
		error("could not check mount status of %s: %s", device,
			strerror(-ret));
		return 1;
	} else if (ret) {
		error("%s is mounted", device);
		return 1;
	}

	root = open_ctree(device, 0, ctree_flags);

	if (!root) {
		error("open ctree failed");
		return 1;
	}

	if (seeding_flag) {
		if (!seeding_value && !force) {
			warning(
"this is dangerous, clearing the seeding flag may cause the derived device not to be mountable!");
			ret = ask_user("We are going to clear the seeding flag, are you sure?");
			if (!ret) {
				fprintf(stderr, "Clear seeding flag canceled\n");
				ret = 1;
				goto out;
			}
		}

		ret = update_seeding_flag(root, seeding_value);
		if (!ret)
			success++;
		total++;
	}

	if (super_flags) {
		ret = set_super_incompat_flags(root, super_flags);
		if (!ret)
			success++;
		total++;
	}

	if (random_fsid || new_fsid_str) {
		if (!force) {
			warning(
	"it's highly recommended to run 'btrfs check' before this operation");
			warning(
	"also canceling running UUID change progress may cause corruption");
			ret = ask_user("We are going to change UUID, are your sure?");
			if (!ret) {
				fprintf(stderr, "UUID change canceled\n");
				ret = 1;
				goto out;
			}
		}
		ret = change_uuid(root->fs_info, new_fsid_str);
		if (!ret)
			success++;
		total++;
	}

	if (success == total) {
		ret = 0;
	} else {
		root->fs_info->readonly = 1;
		ret = 1;
		error("btrfstune failed");
	}
out:
	close_ctree(root);
	btrfs_close_all_devices();

	return ret;
}
Пример #12
0
int main(int ac, char **av)
{
	struct btrfs_root *root;
	int ret;
	u64 num = 0;
	u64 bytenr = 0;

	while(1) {
		int c;
		c = getopt(ac, av, "s:");
		if (c < 0)
			break;
		switch(c) {
			case 's':
				num = arg_strtou64(optarg);
				if (num >= BTRFS_SUPER_MIRROR_MAX) {
					fprintf(stderr,
						"ERROR: super mirror should be less than: %d\n",
						BTRFS_SUPER_MIRROR_MAX);
					exit(1);
				}
				bytenr = btrfs_sb_offset(((int)num));
				break;
			default:
				print_usage();
		}
	}
	set_argv0(av);
	ac = ac - optind;

	if (check_argc_exact(ac, 1))
		print_usage();

	if (bytenr == 0) {
		fprintf(stderr, "Please select the super copy with -s\n");
		print_usage();
	}

	radix_tree_init();

	if((ret = check_mounted(av[optind])) < 0) {
		fprintf(stderr, "Could not check mount status: %s\n", strerror(-ret));
		return ret;
	} else if(ret) {
		fprintf(stderr, "%s is currently mounted. Aborting.\n", av[optind]);
		return -EBUSY;
	}

	root = open_ctree(av[optind], bytenr, 1);

	if (!root) {
		fprintf(stderr, "Open ctree failed\n");
		return 1;
	}

	/* make the super writing code think we've read the first super */
	root->fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
	ret = write_all_supers(root);

	/* we don't close the ctree or anything, because we don't want a real
	 * transaction commit.  We just want the super copy we pulled off the
	 * disk to overwrite all the other copies
	 */
	printf("using SB copy %llu, bytenr %llu\n", (unsigned long long)num,
	       (unsigned long long)bytenr);
	close_ctree(root);
	btrfs_close_all_devices();
	return ret;
}
Пример #13
0
int main(int argc, char **argv)
{
	struct btrfs_fs_info *fs_info;
	struct btrfs_find_root_filter filter = {0};
	struct cache_tree result;
	struct cache_extent *found;
	int ret;

	/* Default to search root tree */
	filter.objectid = BTRFS_ROOT_TREE_OBJECTID;
	filter.match_gen = (u64)-1;
	filter.match_level = (u8)-1;
	while (1) {
		static const struct option long_options[] = {
			{ "help", no_argument, NULL, GETOPT_VAL_HELP},
			{ NULL, 0, NULL, 0 }
		};
		int c = getopt_long(argc, argv, "al:o:g:", long_options, NULL);

		if (c < 0)
			break;

		switch (c) {
		case 'a':
			filter.search_all = 1;
			break;
		case 'o':
			filter.objectid = arg_strtou64(optarg);
			break;
		case 'g':
			filter.generation = arg_strtou64(optarg);
			break;
		case 'l':
			filter.level = arg_strtou64(optarg);
			break;
		case GETOPT_VAL_HELP:
		default:
			find_root_usage();
			exit(c != GETOPT_VAL_HELP);
		}
	}

	set_argv0(argv);
	if (check_argc_min(argc - optind, 1)) {
		find_root_usage();
		exit(1);
	}

	fs_info = open_ctree_fs_info(argv[optind], 0, 0, 0,
			OPEN_CTREE_CHUNK_ROOT_ONLY |
			OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR);
	if (!fs_info) {
		error("open ctree failed");
		exit(1);
	}
	cache_tree_init(&result);

	get_root_gen_and_level(filter.objectid, fs_info,
			       &filter.match_gen, &filter.match_level);
	ret = btrfs_find_root_search(fs_info, &filter, &result, &found);
	if (ret < 0) {
		fprintf(stderr, "Fail to search the tree root: %s\n",
			strerror(-ret));
		goto out;
	}
	if (ret > 0) {
		printf("Found tree root at %llu gen %llu level %u\n",
		       found->start, filter.match_gen, filter.match_level);
		ret = 0;
	}
	print_find_root_result(&result, &filter);
out:
	btrfs_find_root_free(&result);
	close_ctree_fs_info(fs_info);
	btrfs_close_all_devices();
	return ret;
}