#include "props.h"
#include "ctree.h"
#include "utils.h"
+#include "help.h"
static const char * const property_cmd_group_usage[] = {
"btrfs property get/set/list [-t <type>] <object> [<name>] [value]",
NULL
};
-static const char * const cmd_get_usage[] = {
- "btrfs property get [-t <type>] <object> [<name>]",
- "Gets a property from a btrfs object.",
- "If no name is specified, all properties for the given object are",
- "printed.",
- "A filesystem object can be a the filesystem itself, a subvolume,",
- "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].",
- NULL
-};
-
-static const char * const cmd_set_usage[] = {
- "btrfs property set [-t <type>] <object> <name> <value>",
- "Sets a property on a btrfs object.",
- "Please see the help of 'btrfs property get' for a description of",
- "objects and object types.",
- NULL
-};
-
-static const char * const cmd_list_usage[] = {
- "btrfs property list [-t <type>] <object>",
- "Lists available properties with their descriptions for the given object.",
- "Please see the help of 'btrfs property get' for a description of",
- "objects and object types.",
- NULL
-};
-
static int parse_prop(const char *arg, const struct prop_handler *props,
const struct prop_handler **prop_ret)
{
return -1;
}
-static int get_fsid(const char *path, u8 *fsid, int silent)
-{
- int ret;
- int fd;
- struct btrfs_ioctl_fs_info_args args;
-
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- ret = -errno;
- if (!silent)
- fprintf(stderr, "ERROR: open %s failed. %s\n", path,
- strerror(-ret));
- goto out;
- }
-
- ret = ioctl(fd, BTRFS_IOC_FS_INFO, &args);
- if (ret < 0) {
- ret = -errno;
- goto out;
- }
-
- memcpy(fsid, args.fsid, BTRFS_FSID_SIZE);
- ret = 0;
-
-out:
- if (fd != -1)
- close(fd);
- return ret;
-}
-
static int check_btrfs_object(const char *object)
{
int ret;
ret = get_fsid(object, fsid, 0);
if (ret < 0) {
- fprintf(stderr, "ERROR: get_fsid for %s failed. %s\n", object,
- strerror(-ret));
+ error("get_fsid for %s failed: %s", object, strerror(-ret));
goto out;
}
ret = 1;
goto out;
} else if (ret < 0) {
- fprintf(stderr, "ERROR: get_fsid for %s failed. %s\n", tmp,
- strerror(-ret));
+ error("get_fsid for %s failed: %s", tmp, strerror(-ret));
goto out;
}
return ret;
}
-static int print_prop_help(const struct prop_handler *prop)
-{
- fprintf(stdout, "%-20s%s\n", prop->name, prop->desc);
- return 0;
-}
-
static int dump_prop(const struct prop_handler *prop,
const char *object,
int types,
if (!name_and_help)
ret = prop->handler(type, object, prop->name, NULL);
else
- ret = print_prop_help(prop);
+ printf("%-20s%s\n", prop->name, prop->desc);
}
return ret;
}
ret = parse_prop(name, prop_handlers, &prop);
if (ret == -1) {
- fprintf(stderr, "ERROR: property is unknown\n");
+ error("unknown property: %s", name);
ret = 40;
goto out;
}
types &= prop->types;
if (!types) {
- fprintf(stderr,
- "ERROR: object is not compatible with property\n");
+ error("object is not compatible with property: %s", prop->name);
ret = 47;
goto out;
}
if (count_bits(types) > 1) {
- fprintf(stderr,
- "ERROR: type of object is ambiguous. Please specify a type by hand.\n");
+ error("type of object is ambiguous, please use option -t");
ret = 48;
goto out;
}
if (value && prop->read_only) {
- fprintf(stderr, "ERROR: %s is a read-only property.\n",
+ error("property is read-only property: %s",
prop->name);
ret = 51;
goto out;
static void parse_args(int argc, char **argv,
const char * const *usage_str,
int *types, char **object,
- char **name, char **value)
+ char **name, char **value, int min_nonopt_args)
{
int ret;
char *type_str = NULL;
+ int max_nonopt_args = 1;
optind = 1;
while (1) {
}
}
+ if (name)
+ max_nonopt_args++;
+ if (value)
+ max_nonopt_args++;
+
+ if (check_argc_min(argc - optind, min_nonopt_args) ||
+ check_argc_max(argc - optind, max_nonopt_args))
+ usage(usage_str);
+
*types = 0;
if (type_str) {
if (!strcmp(type_str, "s") || !strcmp(type_str, "subvol")) {
!strcmp(type_str, "device")) {
*types = prop_object_dev;
} else {
- fprintf(stderr, "ERROR: invalid object type.\n");
+ error("invalid object type: %s", type_str);
usage(usage_str);
}
}
- if (object && optind < argc)
- *object = argv[optind++];
- if (name && optind < argc)
+ *object = argv[optind++];
+ if (optind < argc)
*name = argv[optind++];
- if (value && optind < argc)
+ if (optind < argc)
*value = argv[optind++];
- if (optind != argc) {
- fprintf(stderr, "ERROR: invalid arguments.\n");
- usage(usage_str);
- }
-
- if (!*types && object && *object) {
+ if (!*types) {
ret = autodetect_object_types(*object, types);
if (ret < 0) {
- fprintf(stderr,
- "ERROR: failed to detect object type. %s\n",
+ error("failed to detect object type: %s",
strerror(-ret));
usage(usage_str);
}
if (!*types) {
- fprintf(stderr,
- "ERROR: object is not a btrfs object.\n");
+ error("object is not a btrfs object: %s", *object);
usage(usage_str);
}
}
}
-static int cmd_get(int argc, char **argv)
+static const char * const cmd_property_get_usage[] = {
+ "btrfs property get [-t <type>] <object> [<name>]",
+ "Gets a property from a btrfs object.",
+ "If no name is specified, all properties for the given object are",
+ "printed.",
+ "A filesystem object can be a the filesystem itself, a subvolume,",
+ "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].",
+ NULL
+};
+
+static int cmd_property_get(int argc, char **argv)
{
int ret;
char *object = NULL;
char *name = NULL;
int types = 0;
- if (check_argc_min(argc, 2) || check_argc_max(argc, 5))
- usage(cmd_get_usage);
-
- parse_args(argc, argv, cmd_get_usage, &types, &object, &name, NULL);
- if (!object) {
- fprintf(stderr, "ERROR: invalid arguments.\n");
- usage(cmd_set_usage);
- }
+ parse_args(argc, argv, cmd_property_get_usage, &types, &object, &name,
+ NULL, 1);
if (name)
ret = setget_prop(types, object, name, NULL);
return ret;
}
-static int cmd_set(int argc, char **argv)
+static const char * const cmd_property_set_usage[] = {
+ "btrfs property set [-t <type>] <object> <name> <value>",
+ "Sets a property on a btrfs object.",
+ "Please see the help of 'btrfs property get' for a description of",
+ "objects and object types.",
+ NULL
+};
+
+static int cmd_property_set(int argc, char **argv)
{
int ret;
char *object = NULL;
char *value = NULL;
int types = 0;
- if (check_argc_min(argc, 4) || check_argc_max(argc, 6))
- usage(cmd_set_usage);
-
- parse_args(argc, argv, cmd_set_usage, &types, &object, &name, &value);
- if (!object || !name || !value) {
- fprintf(stderr, "ERROR: invalid arguments.\n");
- usage(cmd_set_usage);
- }
+ parse_args(argc, argv, cmd_property_set_usage, &types,
+ &object, &name, &value, 3);
ret = setget_prop(types, object, name, value);
return ret;
}
-static int cmd_list(int argc, char **argv)
+static const char * const cmd_property_list_usage[] = {
+ "btrfs property list [-t <type>] <object>",
+ "Lists available properties with their descriptions for the given object.",
+ "Please see the help of 'btrfs property get' for a description of",
+ "objects and object types.",
+ NULL
+};
+
+static int cmd_property_list(int argc, char **argv)
{
int ret;
char *object = NULL;
int types = 0;
- if (check_argc_min(argc, 2) || check_argc_max(argc, 4))
- usage(cmd_list_usage);
-
- parse_args(argc, argv, cmd_list_usage, &types, &object, NULL, NULL);
- if (!object) {
- fprintf(stderr, "ERROR: invalid arguments.\n");
- usage(cmd_set_usage);
- }
+ parse_args(argc, argv, cmd_property_list_usage,
+ &types, &object, NULL, NULL, 1);
ret = dump_props(types, object, 1);
return ret;
}
+static const char property_cmd_group_info[] =
+"modify properties of filesystem objects";
+
const struct cmd_group property_cmd_group = {
- property_cmd_group_usage, NULL, {
- { "get", cmd_get, cmd_get_usage, NULL, 0 },
- { "set", cmd_set, cmd_set_usage, NULL, 0 },
- { "list", cmd_list, cmd_list_usage, NULL, 0 },
- { 0, 0, 0, 0, 0 },
+ property_cmd_group_usage, property_cmd_group_info, {
+ { "get", cmd_property_get,
+ cmd_property_get_usage, NULL, 0 },
+ { "set", cmd_property_set,
+ cmd_property_set_usage, NULL, 0 },
+ { "list", cmd_property_list,
+ cmd_property_list_usage, NULL, 0 },
+ NULL_CMD_STRUCT
}
};