From: Eryu Guan <guan@eryu.me>
To: Christian Brauner <christian.brauner@ubuntu.com>
Cc: Christoph Hellwig <hch@lst.de>,
"Darrick J . Wong" <djwong@kernel.org>,
fstests@vger.kernel.org, David Howells <dhowells@redhat.com>
Subject: Re: [PATCH v9 3/4] xfs/529: quotas and idmapped mounts
Date: Sun, 21 Mar 2021 22:42:06 +0800 [thread overview]
Message-ID: <YFdbPtFPdyyZiL/F@desktop> (raw)
In-Reply-To: <20210316103627.2954121-4-christian.brauner@ubuntu.com>
On Tue, Mar 16, 2021 at 11:36:26AM +0100, Christian Brauner wrote:
> Test that xfs quota behave correctly on idmapped mounts.
> Mount a scratch device with user and group quota support enabled. Create
> directories "unmapped" and "idmapped". Create files in the unampped
> mount and verify quota behavior. Create files through the idmapped mount
> and verify identical behavior.
>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Darrick J. Wong <djwong@kernel.org>
> Cc: fstests@vger.kernel.org
> Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
> ---
> /* v1 */
> patch not present
>
> /* v2 */
> patch not present
>
> /* v3 */
> patch not present
>
> /* v4 */
> patch not present
>
> /* v5 */
> patch not present
>
> /* v6 */
> patch not present
>
> /* v7 */
> patch not present
>
> /* v8 */
> patch introduced
>
> /* v9 */
> - Christian Brauner <christian.brauner@ubuntu.com>:
> - Rebased on current master.
> ---
> .gitignore | 1 +
> src/idmapped-mounts/Makefile | 14 +-
> src/idmapped-mounts/mount-idmapped.c | 428 +++++++++++++++++
> src/idmapped-mounts/utils.c | 2 +-
> src/idmapped-mounts/utils.h | 1 +
> tests/xfs/529 | 373 +++++++++++++++
> tests/xfs/529.out | 657 +++++++++++++++++++++++++++
> tests/xfs/group | 1 +
> 8 files changed, 1472 insertions(+), 5 deletions(-)
> create mode 100644 src/idmapped-mounts/mount-idmapped.c
> create mode 100644 tests/xfs/529
> create mode 100644 tests/xfs/529.out
>
> diff --git a/.gitignore b/.gitignore
> index 3229bb26..4cc9c807 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -179,6 +179,7 @@
> /src/aio-dio-regress/aiocp
> /src/aio-dio-regress/aiodio_sparse2
> /src/idmapped-mounts/idmapped-mounts
> +/src/idmapped-mounts/mount-idmapped
> /src/log-writes/replay-log
> /src/perf/*.pyc
>
> diff --git a/src/idmapped-mounts/Makefile b/src/idmapped-mounts/Makefile
> index 6a934146..40bf9164 100644
> --- a/src/idmapped-mounts/Makefile
> +++ b/src/idmapped-mounts/Makefile
> @@ -3,9 +3,10 @@
> TOPDIR = ../..
> include $(TOPDIR)/include/builddefs
>
> -TARGETS = idmapped-mounts
> +TARGETS = idmapped-mounts mount-idmapped
> +CFILES_IDMAPPED_MOUNTS = idmapped-mounts.c utils.c
> +CFILES_MOUNT_IDMAPPED = mount-idmapped.c utils.c
>
> -CFILES = idmapped-mounts.c utils.c
> HFILES = missing.h utils.h
> LLDLIBS += -pthread
> LDIRT = $(TARGETS)
> @@ -24,12 +25,17 @@ depend: .dep
>
> include $(BUILDRULES)
>
> -$(TARGETS): $(CFILES)
> +idmapped-mounts:
> @echo " [CC] $@"
> - $(Q)$(LTLINK) $(CFILES) -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
> + $(Q)$(LTLINK) $(CFILES_IDMAPPED_MOUNTS) -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
> +
> +mount-idmapped:
> + @echo " [CC] $@"
> + $(Q)$(LTLINK) $(CFILES_MOUNT_IDMAPPED) -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
>
> install:
> $(INSTALL) -m 755 -d $(PKG_LIB_DIR)/src/idmapped-mounts
> $(INSTALL) -m 755 $(TARGETS) $(PKG_LIB_DIR)/src/idmapped-mounts
> + $(INSTALL) -m 755 $(TARGETS) $(PKG_LIB_DIR)/src/mount-idmapped
>
> -include .dep
> diff --git a/src/idmapped-mounts/mount-idmapped.c b/src/idmapped-mounts/mount-idmapped.c
> new file mode 100644
> index 00000000..f127cdc7
> --- /dev/null
> +++ b/src/idmapped-mounts/mount-idmapped.c
> @@ -0,0 +1,428 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#ifndef _GNU_SOURCE
> +#define _GNU_SOURCE
> +#endif
> +
> +#include "../global.h"
> +
> +#include <dirent.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <getopt.h>
> +#include <libgen.h>
> +#include <limits.h>
> +#include <linux/bpf.h>
> +#include <linux/sched.h>
> +#include <linux/seccomp.h>
> +#include <sched.h>
> +#include <signal.h>
> +#include <stdbool.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/mman.h>
> +#include <sys/stat.h>
> +#include <sys/syscall.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +#include <unistd.h>
> +
> +#include "missing.h"
> +#include "utils.h"
> +
> +/* A few helpful macros. */
> +#define STRLITERALLEN(x) (sizeof(""x"") - 1)
> +
> +#define INTTYPE_TO_STRLEN(type) \
> + (2 + (sizeof(type) <= 1 \
> + ? 3 \
> + : sizeof(type) <= 2 \
> + ? 5 \
> + : sizeof(type) <= 4 \
> + ? 10 \
> + : sizeof(type) <= 8 ? 20 : sizeof(int[-2 * (sizeof(type) > 8)])))
> +
> +#define syserror(format, ...) \
> + ({ \
> + fprintf(stderr, format, ##__VA_ARGS__); \
> + (-errno); \
> + })
> +
> +#define syserror_set(__ret__, format, ...) \
> + ({ \
> + typeof(__ret__) __internal_ret__ = (__ret__); \
> + errno = labs(__ret__); \
> + fprintf(stderr, format, ##__VA_ARGS__); \
> + __internal_ret__; \
> + })
> +
> +struct list {
> + void *elem;
> + struct list *next;
> + struct list *prev;
> +};
> +
> +#define list_for_each(__iterator, __list) \
> + for (__iterator = (__list)->next; __iterator != __list; __iterator = __iterator->next)
> +
> +static inline void list_init(struct list *list)
> +{
> + list->elem = NULL;
> + list->next = list->prev = list;
> +}
> +
> +static inline int list_empty(const struct list *list)
> +{
> + return list == list->next;
> +}
> +
> +static inline void __list_add(struct list *new, struct list *prev, struct list *next)
> +{
> + next->prev = new;
> + new->next = next;
> + new->prev = prev;
> + prev->next = new;
> +}
> +
> +static inline void list_add_tail(struct list *head, struct list *list)
> +{
> + __list_add(list, head->prev, head);
> +}
> +
> +typedef enum idmap_type_t {
> + ID_TYPE_UID,
> + ID_TYPE_GID
> +} idmap_type_t;
> +
> +struct id_map {
> + idmap_type_t map_type;
> + __u32 nsid;
> + __u32 hostid;
> + __u32 range;
> +};
> +
> +static struct list active_map;
> +
> +static int add_map_entry(__u32 id_host,
> + __u32 id_ns,
> + __u32 range,
> + idmap_type_t map_type)
> +{
> + struct list *new_list = NULL;
> + struct id_map *newmap = NULL;
> +
> + newmap = malloc(sizeof(*newmap));
> + if (!newmap)
> + return -ENOMEM;
> +
> + new_list = malloc(sizeof(struct list));
> + if (!new_list) {
> + free(newmap);
> + return -ENOMEM;
> + }
> +
> + *newmap = (struct id_map){
> + .hostid = id_host,
> + .nsid = id_ns,
> + .range = range,
> + .map_type = map_type,
> + };
> +
> + new_list->elem = newmap;
> + list_add_tail(&active_map, new_list);
> + return 0;
> +}
> +
> +static int parse_map(char *map)
> +{
> + char types[2] = {'u', 'g'};
> + int ret;
> + __u32 id_host, id_ns, range;
> + char which;
> +
> + if (!map)
> + return -1;
> +
> + ret = sscanf(map, "%c:%u:%u:%u", &which, &id_ns, &id_host, &range);
> + if (ret != 4)
> + return -1;
> +
> + if (which != 'b' && which != 'u' && which != 'g')
> + return -1;
> +
> + for (int i = 0; i < 2; i++) {
> + idmap_type_t map_type;
> +
> + if (which != types[i] && which != 'b')
> + continue;
> +
> + if (types[i] == 'u')
> + map_type = ID_TYPE_UID;
> + else
> + map_type = ID_TYPE_GID;
> +
> + ret = add_map_entry(id_host, id_ns, range, map_type);
> + if (ret < 0)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int write_id_mapping(idmap_type_t map_type, pid_t pid, const char *buf, size_t buf_size)
> +{
> + int fd = -EBADF, setgroups_fd = -EBADF;
> + int fret = -1;
> + int ret;
> + char path[STRLITERALLEN("/proc") + INTTYPE_TO_STRLEN(pid_t) +
> + STRLITERALLEN("/setgroups") + 1];
> +
> + if (geteuid() != 0 && map_type == ID_TYPE_GID) {
> + ret = snprintf(path, sizeof(path), "/proc/%d/setgroups", pid);
> + if (ret < 0 || ret >= sizeof(path))
> + goto out;
> +
> + setgroups_fd = open(path, O_WRONLY | O_CLOEXEC);
> + if (setgroups_fd < 0 && errno != ENOENT) {
> + syserror("Failed to open \"%s\"", path);
> + goto out;
> + }
> +
> + if (setgroups_fd >= 0) {
> + ret = write_nointr(setgroups_fd, "deny\n", STRLITERALLEN("deny\n"));
> + if (ret != STRLITERALLEN("deny\n")) {
> + syserror("Failed to write \"deny\" to \"/proc/%d/setgroups\"", pid);
> + goto out;
> + }
> + }
> + }
> +
> + ret = snprintf(path, sizeof(path), "/proc/%d/%cid_map", pid, map_type == ID_TYPE_UID ? 'u' : 'g');
> + if (ret < 0 || ret >= sizeof(path))
> + goto out;
> +
> + fd = open(path, O_WRONLY | O_CLOEXEC);
> + if (fd < 0) {
> + syserror("Failed to open \"%s\"", path);
> + goto out;
> + }
> +
> + ret = write_nointr(fd, buf, buf_size);
> + if (ret != buf_size) {
> + syserror("Failed to write %cid mapping to \"%s\"",
> + map_type == ID_TYPE_UID ? 'u' : 'g', path);
> + goto out;
> + }
> +
> + fret = 0;
> +out:
> + if (fd >= 0)
> + close(fd);
> + if (setgroups_fd >= 0)
> + close(setgroups_fd);
> +
> + return fret;
> +}
> +
> +static int map_ids_from_idmap(struct list *idmap, pid_t pid)
> +{
> + int fill, left;
> + char mapbuf[4096] = {};
> + bool had_entry = false;
> +
> + for (idmap_type_t map_type = ID_TYPE_UID, u_or_g = 'u';
> + map_type <= ID_TYPE_GID; map_type++, u_or_g = 'g') {
> + char *pos = mapbuf;
> + int ret;
> + struct list *iterator;
> +
> +
> + list_for_each(iterator, idmap) {
> + struct id_map *map = iterator->elem;
> + if (map->map_type != map_type)
> + continue;
> +
> + had_entry = true;
> +
> + left = 4096 - (pos - mapbuf);
> + fill = snprintf(pos, left, "%u %u %u\n", map->nsid, map->hostid, map->range);
> + /*
> + * The kernel only takes <= 4k for writes to
> + * /proc/<pid>/{g,u}id_map
> + */
> + if (fill <= 0 || fill >= left)
> + return syserror_set(-E2BIG, "Too many %cid mappings defined", u_or_g);
> +
> + pos += fill;
> + }
> + if (!had_entry)
> + continue;
> +
> + ret = write_id_mapping(map_type, pid, mapbuf, pos - mapbuf);
> + if (ret < 0)
> + return syserror("Failed to write mapping: %s", mapbuf);
> +
> + memset(mapbuf, 0, sizeof(mapbuf));
> + }
> +
> + return 0;
> +}
> +
> +static int get_userns_fd_from_idmap(struct list *idmap)
> +{
> + int ret;
> + pid_t pid;
> + char path_ns[STRLITERALLEN("/proc") + INTTYPE_TO_STRLEN(pid_t) +
> + STRLITERALLEN("/ns/user") + 1];
> +
> + pid = do_clone(get_userns_fd_cb, NULL, CLONE_NEWUSER | CLONE_NEWNS);
> + if (pid < 0)
> + return -errno;
> +
> + ret = map_ids_from_idmap(idmap, pid);
> + if (ret < 0)
> + return ret;
> +
> + ret = snprintf(path_ns, sizeof(path_ns), "/proc/%d/ns/user", pid);
> + if (ret < 0 || (size_t)ret >= sizeof(path_ns))
> + ret = -EIO;
> + else
> + ret = open(path_ns, O_RDONLY | O_CLOEXEC | O_NOCTTY);
> +
> + (void)kill(pid, SIGKILL);
> + (void)wait_for_pid(pid);
> + return ret;
> +}
> +
> +static inline bool strnequal(const char *str, const char *eq, size_t len)
> +{
> + return strncmp(str, eq, len) == 0;
> +}
> +
> +static void usage(void)
> +{
> + const char *text = "\
> +mount-idmapped --map-mount=<idmap> <source> <target>\n\
> +\n\
> +Create an idmapped mount of <source> at <target>\n\
> +Options:\n\
> + --map-mount=<idmap>\n\
> + Specify an idmap for the <target> mount in the format\n\
> + <idmap-type>:<id-from>:<id-to>:<id-range>\n\
> + The <idmap-type> can be:\n\
> + \"b\" or \"both\" -> map both uids and gids\n\
> + \"u\" or \"uid\" -> map uids\n\
> + \"g\" or \"gid\" -> map gids\n\
> + For example, specifying:\n\
> + both:1000:1001:1 -> map uid and gid 1000 to uid and gid 1001 in <target> and no other ids\n\
> + uid:20000:100000:1000 -> map uid 20000 to uid 100000, uid 20001 to uid 100001 [...] in <target>\n\
> + Currently up to 340 separate idmappings may be specified.\n\n\
> + --map-mount=/proc/<pid>/ns/user\n\
> + Specify a path to a user namespace whose idmap is to be used.\n\n\
> + --recursive\n\
> + Copy the whole mount tree from <source> and apply the idmap to everyone at <target>.\n\n\
> +Examples:\n\
> + - Create an idmapped mount of /source on /target with both ('b') uids and gids mapped:\n\
> + mount-idmapped --map-mount b:0:10000:10000 /source /target\n\n\
> + - Create an idmapped mount of /source on /target with uids ('u') and gids ('g') mapped separately:\n\
> + mount-idmapped --map-mount u:0:10000:10000 g:0:20000:20000 /source /target\n\n\
> +";
> + fprintf(stderr, "%s", text);
> + _exit(EXIT_SUCCESS);
> +}
> +
> +#define exit_usage(format, ...) \
> + ({ \
> + fprintf(stderr, format, ##__VA_ARGS__); \
> + usage(); \
> + })
> +
> +#define exit_log(format, ...) \
> + ({ \
> + fprintf(stderr, format, ##__VA_ARGS__); \
> + exit(EXIT_FAILURE); \
> + })
> +
> +static const struct option longopts[] = {
> + {"map-mount", required_argument, 0, 'a'},
> + {"help", no_argument, 0, 'c'},
> + {"recursive", no_argument, 0, 'd'},
> + { NULL, 0, 0, 0 },
> +};
> +
> +int main(int argc, char *argv[])
> +{
> + int fd_userns = -EBADF;
> + int index = 0;
> + const char *source = NULL, *target = NULL;
> + bool recursive = false;
> + int fd_tree, new_argc, ret;
> + char *const *new_argv;
> +
> + list_init(&active_map);
> + while ((ret = getopt_long_only(argc, argv, "", longopts, &index)) != -1) {
> + switch (ret) {
> + case 'a':
> + if (strnequal(optarg, "/proc", STRLITERALLEN("/proc/"))) {
> + fd_userns = open(optarg, O_RDONLY | O_CLOEXEC);
> + if (fd_userns < 0)
> + exit_log("%m - Failed top open user namespace path %s\n", optarg);
> + break;
> + }
> +
> + ret = parse_map(optarg);
> + if (ret < 0)
> + exit_log("Failed to parse idmaps for mount\n");
> + break;
> + case 'd':
> + recursive = true;
> + break;
> + case 'c':
> + /* fallthrough */
> + default:
> + usage();
> + }
> + }
> +
> + new_argv = &argv[optind];
> + new_argc = argc - optind;
> + if (new_argc < 2)
> + exit_usage("Missing source or target mountpoint\n\n");
> + source = new_argv[0];
> + target = new_argv[1];
> +
> + fd_tree = sys_open_tree(-EBADF, source,
> + OPEN_TREE_CLONE |
> + OPEN_TREE_CLOEXEC |
> + AT_EMPTY_PATH |
> + (recursive ? AT_RECURSIVE : 0));
> + if (fd_tree < 0) {
> + exit_log("%m - Failed to open %s\n", source);
> + exit(EXIT_FAILURE);
> + }
> +
> + if (!list_empty(&active_map)) {
> + struct mount_attr attr = {
> + .attr_set = MOUNT_ATTR_IDMAP,
> + };
> +
> + attr.userns_fd = get_userns_fd_from_idmap(&active_map);
> + if (attr.userns_fd < 0)
> + exit_log("%m - Failed to create user namespace\n");
> +
> + ret = sys_mount_setattr(fd_tree, "", AT_EMPTY_PATH | AT_RECURSIVE,
> + &attr, sizeof(attr));
> + if (ret < 0)
> + exit_log("%m - Failed to change mount attributes\n");
> + close(attr.userns_fd);
> + }
> +
> + ret = sys_move_mount(fd_tree, "", -EBADF, target,
> + MOVE_MOUNT_F_EMPTY_PATH);
> + if (ret < 0)
> + exit_log("%m - Failed to attach mount to %s\n", target);
> + close(fd_tree);
> +
> + exit(EXIT_SUCCESS);
> +}
> diff --git a/src/idmapped-mounts/utils.c b/src/idmapped-mounts/utils.c
> index b27ba445..977443f1 100644
> --- a/src/idmapped-mounts/utils.c
> +++ b/src/idmapped-mounts/utils.c
> @@ -88,7 +88,7 @@ pid_t do_clone(int (*fn)(void *), void *arg, int flags)
> #endif
> }
>
> -static int get_userns_fd_cb(void *data)
> +int get_userns_fd_cb(void *data)
> {
> return kill(getpid(), SIGSTOP);
> }
> diff --git a/src/idmapped-mounts/utils.h b/src/idmapped-mounts/utils.h
> index 93425731..efbf3bc3 100644
> --- a/src/idmapped-mounts/utils.h
> +++ b/src/idmapped-mounts/utils.h
> @@ -20,6 +20,7 @@
> #include "missing.h"
>
> extern pid_t do_clone(int (*fn)(void *), void *arg, int flags);
> +extern int get_userns_fd_cb(void *data);
> extern int get_userns_fd(unsigned long nsid, unsigned long hostid,
> unsigned long range);
> extern ssize_t read_nointr(int fd, void *buf, size_t count);
> diff --git a/tests/xfs/529 b/tests/xfs/529
> new file mode 100644
> index 00000000..67251818
> --- /dev/null
> +++ b/tests/xfs/529
> @@ -0,0 +1,373 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Copyright (c) 2021 Christian Brauner <christian.brauner@ubuntu.com>
> +# All Rights Reserved.
> +#
> +# FS QA Test No. 529
> +#
> +# Exercise basic xfs_quota functionality (user/group/project quota)
> +# Use of "sync" mount option here is an attempt to get deterministic
> +# allocator behaviour.
> +#
> +seq=`basename $0`
> +seqres=$RESULT_DIR/$seq
> +echo "QA output created by $seq"
> +
> +here=`pwd`
> +tmp=/tmp/$$
> +status=1 # failure is the default!
> +trap "_cleanup; exit \$status" 0 1 2 3 15
> +
> +_cleanup()
> +{
> + cd /
> + rm -f $tmp.*
Seems we should do wipe_mounts in _cleanup as well, in case test exits
in the middle of the test with idmapped mount still mounted.
> +}
> +
> +# get standard environment, filters and checks
> +. ./common/rc
> +. ./common/filter
> +. ./common/quota
> +
> +# remove previous $seqres.full before test
> +rm -f $seqres.full
> +
> +# real QA test starts here
> +_supported_fs xfs
> +_require_idmapped_mounts
> +_require_scratch
> +_require_xfs_quota
> +_require_user fsgqa
> +_require_user fsgqa2
> +_require_group fsgqa
> +_require_group fsgqa2
> +
> +_scratch_mkfs_xfs >>$seqres.full 2>&1
> +
> +uqid=`id -u fsgqa`
> +gqid=`id -g fsgqa`
> +
> +uqid2=`id -u fsgqa2`
> +gqid2=`id -g fsgqa2`
> +
> +pqid=10
> +cat >$tmp.projects <<EOF
> +$pqid:$SCRATCH_MNT
> +EOF
> +
> +cat >$tmp.projid <<EOF
> +root:0
> +fsgqa:$pqid
> +EOF
> +
> +create_files_unmapped()
> +{
> + local bs=$1
> + local inum=$2
> +
> + echo "Using type=$type id=$id" >> $seqres.full
> +
> + for ((i=0; i<$((inum-1)); i++)); do
> + _file_as_id $SCRATCH_MNT/unmapped/inode$i $id $type 1024 0
> + done
> +
> + _file_as_id $SCRATCH_MNT/unmapped/block $id $type $bs 1
> +}
> +
> +create_files_idmapped()
> +{
> + local bs=$1
> + local inum=$2
> +
> + echo "Using type=$type id=$id2" >> $seqres.full
> +
> + for ((i=0; i<$((inum-1)); i++)); do
> + _file_as_id $SCRATCH_MNT/idmapped/inode$i $id2 $type 1024 0
> + done
> +
> + _file_as_id $SCRATCH_MNT/idmapped/block $id2 $type $bs 1
> +}
> +
> +clean_files()
> +{
> + rm -rf $SCRATCH_MNT/unmapped 2>/dev/null
> + rm -rf $SCRATCH_MNT/idmapped 2>/dev/null
> + rm -rf $tmp.quot 2>/dev/null
> + rm -rf $tmp.quota 2>/dev/null
> +}
> +
> +filter_quot()
> +{
> + _filter_quota | grep -v "root \|\#0 " \
> + | sed -e '/#[0-9]*/s/#[0-9]*/#ID/g'
> +}
> +
> +filter_report()
> +{
> + _filter_quota | grep -v "^root \|^\#0 " \
> + | sed -e '/^#[0-9]*/s/^#[0-9]*/#ID/g'
> +}
> +
> +filter_quota()
> +{
> + _filter_quota | sed -e "/Disk quotas for/s/([0-9]*)/(ID)/g" \
> + -e "/Disk quotas for/s/#[0-9]*/#ID/g"
> +}
> +
> +filter_state()
> +{
> + _filter_quota | sed -e "s/Inode: #[0-9]* (0 blocks, 0 extents)/Inode: #[INO] (0 blocks, 0 extents)/g" \
> + -e "s/Inode: #[0-9]* ([0-9]* blocks, [0-9]* extents)/Inode: #[INO] (X blocks, Y extents)/g" \
> + -e "/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/s/ [0-9][0-9]:[0-9][0-9]:[0-9][0-9]//g" \
> + -e '/max warnings:/d'
> +}
> +
> +test_quot()
> +{
> + local opt="$*"
> +
> + echo "checking quot command (type=$type)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "quot -$type $opt -bi" $SCRATCH_MNT | filter_quot
> +}
> +
> +test_report()
> +{
> + local opt="$*"
> +
> + echo "checking report command (type=$type)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "report -$type $opt -bi" \
> + $SCRATCH_MNT | filter_report
> +}
> +
> +test_quota()
> +{
> + local opt="$*"
> +
> + echo "checking quota command (type=$type)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "quota -$type $opt -bi $id" \
> + $SCRATCH_MNT | filter_quota
> +}
> +
> +test_limit()
> +{
> + local bs=$1
> + local bh=$2
> + local is=$3
> + local ih=$4
> +
> + echo "checking limit command (type=$type, bsoft=$bs, bhard=$bh, isoft=$is, ihard=$ih)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "limit -$type bsoft=$bs bhard=$bh fsgqa" \
> + -c "limit -$type isoft=$is ihard=$ih fsgqa" \
> + $SCRATCH_MNT
> +
> + # let the timer day transition happen
> + sleep 2
> +}
> +
> +test_timer()
> +{
> + echo "checking timer command (type=$type)"
> + # set 3days+1h for time won't become 2days soon
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "timer -$type -bi 73h" \
> + $SCRATCH_MNT | _filter_scratch
> +}
> +
> +test_disable()
> +{
> + echo "checking disable command (type=$type)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "disable -$type -v" \
> + $SCRATCH_MNT | filter_state
> +}
> +
> +test_enable()
> +{
> + echo "checking enable command (type=$type)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "enable -$type -v" $SCRATCH_MNT | filter_state
> +}
> +
> +test_off()
> +{
> + echo "checking off command (type=$type)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "off -$type -v" $SCRATCH_MNT | _filter_scratch
> +}
> +
> +test_remove()
> +{
> + echo "checking remove command (type=$type)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "remove -$type -v" \
> + $SCRATCH_MNT | _filter_scratch
> +}
> +
> +test_state()
> +{
> + echo "checking state command (type=$type)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "state -$type" $SCRATCH_MNT | filter_state
> +}
> +
> +test_dump()
> +{
> + echo "checking dump command (type=$type)"
> + rm -f $tmp.backup 2>>/dev/null
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "dump -$type -f $tmp.backup" \
> + $SCRATCH_MNT | _filter_scratch
> +}
> +
> +test_restore()
> +{
> + echo "checking restore command (type=$type)"
> + $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> + -c "restore -$type -f $tmp.backup" \
> + $SCRATCH_MNT | _filter_scratch
> +}
> +
> +_wipe_mounts()
Local functions don't need the leading "_" in function name.
> +{
> + umount -l -q "${SCRATCH_MNT}/idmapped" >/dev/null 2>&1
$UMOUNT_PROG, and you already dump stderr and stdout to /dev/null, -q
seems not necessary.
> + _scratch_unmount >/dev/null 2>&1
> +}
> +
> +_wipe_scratch()
> +{
> + _wipe_mounts
> + _scratch_mkfs_xfs >>$seqres.full 2>&1
> +}
> +
> +_qmount_idmapped()
> +{
> + _wipe_mounts
> + _try_scratch_mount || _fail "qmount failed"
> +
> + mkdir -p "${SCRATCH_MNT}/unmapped"
> + mkdir -p "${SCRATCH_MNT}/idmapped"
> +
> + $here/src/idmapped-mounts/mount-idmapped --map-mount b:$id:$id2:1 --map-mount b:0:0:1 "$SCRATCH_MNT/unmapped" "$SCRATCH_MNT/idmapped" || _fail "mount-idmapped failed"
> +
> + chmod ugo+rwx $SCRATCH_MNT
> + chmod ugo+rwx $SCRATCH_MNT/unmapped
> + chmod ugo+rwx $SCRATCH_MNT/idmapped
> +}
> +
> +test_xfs_quota()
> +{
> + # init quota
> + echo "init quota limit and timer, and dump it"
> + if [ "$idmapped" -eq 1 ]; then
> + echo "create_files_idmapped 1024k 15"; create_files_idmapped 1024k 15
> + else
> + echo "create_files_unmapped 1024k 15"; create_files_unmapped 1024k 15
> + fi
> + echo "quota remount"; _qmount_idmapped
> + echo ; test_quot
> + echo ; test_timer
> + echo ; test_limit 512k 2048k 10 20
> + echo ; test_dump
> +
> + # report options test
> + echo "report options test"
> + echo ; test_report
> + echo "-N option"; test_report -N
> + echo "-L -U options"; test_report -L $id -U $id
> + echo "-t option"; test_report -t
> + echo "-n option"; test_report -n
> + echo "-h option"; test_report -h
> +
> + # quot options test
> + echo "quot options test"
> + echo ; test_quot
> + echo "-f option"; test_quot -f $tmp.quot
> + cat $tmp.quot | filter_quot
> + echo "-n option"; test_quot -n
> +
> + # quota options test
> + echo ; test_quota
> + echo "-f option"; test_quota -f $tmp.quota
> + cat $tmp.quota | filter_quota
> + echo "-N option"; test_quota -N
> + echo "-n option"; test_quota -n
> + echo "-h option"; test_quota -h
> +
> + # disable/enable test
> + echo "disable quota"
> + echo ; test_disable
> + echo ; test_report -N
> + echo "expect a remove error at here"; test_remove
> + echo ; test_enable
> + echo ; test_report -N
> +
> + # off and remove test
> + echo "off and remove test"
> + echo ; test_limit 100m 100m 100 100
> + echo ; test_quota -N
> + echo ; test_off
> + echo ; test_state
> + echo ; test_remove
> + echo ; test_report -N
> + echo "quota remount"; _qmount_idmapped
> + echo ; test_report -N
> +
> + # restore test
> + echo "restore quota"
> + echo ; test_restore
> + echo ; test_report -N
> + echo ; test_state
> + echo "cleanup files"; clean_files
> +}
> +
> +echo "----------------------- uquota,sync,unmapped ---------------------------"
> +_wipe_scratch
> +_qmount_option "uquota,sync"
> +type=u
> +id=$uqid
> +id2=$uqid2
> +idmapped=0
> +_qmount_idmapped
> +test_xfs_quota
> +
> +echo "----------------------- uquota,sync,idmapped ---------------------------"
> +_wipe_scratch
> +_qmount_option "uquota,sync"
> +type=u
> +id=$uqid
> +id2=$uqid2
> +idmapped=1
> +_qmount_idmapped
> +test_xfs_quota
> +
> +echo "----------------------- gquota,sync,unmapped ---------------------------"
> +_wipe_scratch
> +_qmount_option "gquota,sync"
> +type=g
> +id=$gqid
> +id2=$gqid2
> +idmapped=0
> +_qmount_idmapped
> +test_xfs_quota
> +
> +echo "----------------------- gquota,sync,idmapped ---------------------------"
> +_wipe_scratch
> +_qmount_option "gquota,sync"
> +type=g
> +id=$gqid
> +id2=$gqid2
> +idmapped=1
> +_qmount_idmapped
> +test_xfs_quota
> +
> +umount -l -q "${SCRATCH_MNT}/idmapped" >/dev/null 2>&1
> +_scratch_unmount
Could use wipe_mounts here?
Thanks,
Eryu
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/xfs/529.out b/tests/xfs/529.out
> new file mode 100644
> index 00000000..7d2cd96d
> --- /dev/null
> +++ b/tests/xfs/529.out
> @@ -0,0 +1,657 @@
> +QA output created by 529
> +----------------------- uquota,sync,unmapped ---------------------------
> +init quota limit and timer, and dump it
> +create_files_unmapped 1024k 15
> +quota remount
> +
> +checking quot command (type=u)
> +SCRATCH_DEV (SCRATCH_MNT) User:
> + 1024 15 fsgqa
> +
> +checking timer command (type=u)
> +
> +checking limit command (type=u, bsoft=512k, bhard=2048k, isoft=10, ihard=20)
> +
> +checking dump command (type=u)
> +report options test
> +
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-N option
> +checking report command (type=u)
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-L -U options
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-t option
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-n option
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-h option
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace
> +---------- --------------------------------- ---------------------------------
> +fsgqa 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days]
> +
> +quot options test
> +
> +checking quot command (type=u)
> +SCRATCH_DEV (SCRATCH_MNT) User:
> + 1024 15 fsgqa
> +-f option
> +checking quot command (type=u)
> +SCRATCH_DEV (SCRATCH_MNT) User:
> + 1024 15 fsgqa
> +-n option
> +checking quot command (type=u)
> +SCRATCH_DEV (SCRATCH_MNT) User:
> + 1024 15 #ID
> +
> +checking quota command (type=u)
> +Disk quotas for User fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-f option
> +checking quota command (type=u)
> +Disk quotas for User fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-N option
> +checking quota command (type=u)
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-n option
> +checking quota command (type=u)
> +Disk quotas for User #ID (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-h option
> +checking quota command (type=u)
> +Disk quotas for User fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +disable quota
> +
> +checking disable command (type=u)
> +User quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: OFF
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [3 days]
> +Inodes grace time: [3 days]
> +Realtime Blocks grace time: [7 days]
> +
> +checking report command (type=u)
> +fsgqa 1024 512 2048 00 [--------] 15 10 20 00 [--------]
> +
> +expect a remove error at here
> +checking remove command (type=u)
> +XFS_QUOTARM: Invalid argument
> +
> +checking enable command (type=u)
> +User quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: ON
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [3 days]
> +Inodes grace time: [3 days]
> +Realtime Blocks grace time: [7 days]
> +
> +checking report command (type=u)
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +off and remove test
> +
> +checking limit command (type=u, bsoft=100m, bhard=100m, isoft=100, ihard=100)
> +
> +checking quota command (type=u)
> +SCRATCH_DEV 1024 102400 102400 00 [--------] 15 100 100 00 [--------] SCRATCH_MNT
> +
> +checking off command (type=u)
> +User quota are not enabled on SCRATCH_DEV
> +
> +checking state command (type=u)
> +
> +checking remove command (type=u)
> +User quota are not enabled on SCRATCH_DEV
> +
> +checking report command (type=u)
> +
> +quota remount
> +
> +checking report command (type=u)
> +fsgqa 1024 0 0 00 [--------] 15 0 0 00 [--------]
> +
> +restore quota
> +
> +checking restore command (type=u)
> +
> +checking report command (type=u)
> +fsgqa 1024 512 2048 00 [7 days] 15 10 20 00 [7 days]
> +
> +
> +checking state command (type=u)
> +User quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: ON
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [7 days]
> +Inodes grace time: [7 days]
> +Realtime Blocks grace time: [7 days]
> +cleanup files
> +----------------------- uquota,sync,idmapped ---------------------------
> +init quota limit and timer, and dump it
> +create_files_idmapped 1024k 15
> +quota remount
> +
> +checking quot command (type=u)
> +SCRATCH_DEV (SCRATCH_MNT) User:
> + 1024 15 fsgqa
> +
> +checking timer command (type=u)
> +
> +checking limit command (type=u, bsoft=512k, bhard=2048k, isoft=10, ihard=20)
> +
> +checking dump command (type=u)
> +report options test
> +
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-N option
> +checking report command (type=u)
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-L -U options
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-t option
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-n option
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-h option
> +checking report command (type=u)
> +User quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace
> +---------- --------------------------------- ---------------------------------
> +fsgqa 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days]
> +
> +quot options test
> +
> +checking quot command (type=u)
> +SCRATCH_DEV (SCRATCH_MNT) User:
> + 1024 15 fsgqa
> +-f option
> +checking quot command (type=u)
> +SCRATCH_DEV (SCRATCH_MNT) User:
> + 1024 15 fsgqa
> +-n option
> +checking quot command (type=u)
> +SCRATCH_DEV (SCRATCH_MNT) User:
> + 1024 15 #ID
> +
> +checking quota command (type=u)
> +Disk quotas for User fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-f option
> +checking quota command (type=u)
> +Disk quotas for User fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-N option
> +checking quota command (type=u)
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-n option
> +checking quota command (type=u)
> +Disk quotas for User #ID (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-h option
> +checking quota command (type=u)
> +Disk quotas for User fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +disable quota
> +
> +checking disable command (type=u)
> +User quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: OFF
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [3 days]
> +Inodes grace time: [3 days]
> +Realtime Blocks grace time: [7 days]
> +
> +checking report command (type=u)
> +fsgqa 1024 512 2048 00 [--------] 15 10 20 00 [--------]
> +
> +expect a remove error at here
> +checking remove command (type=u)
> +XFS_QUOTARM: Invalid argument
> +
> +checking enable command (type=u)
> +User quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: ON
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [3 days]
> +Inodes grace time: [3 days]
> +Realtime Blocks grace time: [7 days]
> +
> +checking report command (type=u)
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +off and remove test
> +
> +checking limit command (type=u, bsoft=100m, bhard=100m, isoft=100, ihard=100)
> +
> +checking quota command (type=u)
> +SCRATCH_DEV 1024 102400 102400 00 [--------] 15 100 100 00 [--------] SCRATCH_MNT
> +
> +checking off command (type=u)
> +User quota are not enabled on SCRATCH_DEV
> +
> +checking state command (type=u)
> +
> +checking remove command (type=u)
> +User quota are not enabled on SCRATCH_DEV
> +
> +checking report command (type=u)
> +
> +quota remount
> +
> +checking report command (type=u)
> +fsgqa 1024 0 0 00 [--------] 15 0 0 00 [--------]
> +
> +restore quota
> +
> +checking restore command (type=u)
> +
> +checking report command (type=u)
> +fsgqa 1024 512 2048 00 [7 days] 15 10 20 00 [7 days]
> +
> +
> +checking state command (type=u)
> +User quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: ON
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [7 days]
> +Inodes grace time: [7 days]
> +Realtime Blocks grace time: [7 days]
> +cleanup files
> +----------------------- gquota,sync,unmapped ---------------------------
> +init quota limit and timer, and dump it
> +create_files_unmapped 1024k 15
> +quota remount
> +
> +checking quot command (type=g)
> +SCRATCH_DEV (SCRATCH_MNT) Group:
> + 1024 15 fsgqa
> +
> +checking timer command (type=g)
> +
> +checking limit command (type=g, bsoft=512k, bhard=2048k, isoft=10, ihard=20)
> +
> +checking dump command (type=g)
> +report options test
> +
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-N option
> +checking report command (type=g)
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-L -U options
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-t option
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-n option
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-h option
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace
> +---------- --------------------------------- ---------------------------------
> +fsgqa 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days]
> +
> +quot options test
> +
> +checking quot command (type=g)
> +SCRATCH_DEV (SCRATCH_MNT) Group:
> + 1024 15 fsgqa
> +-f option
> +checking quot command (type=g)
> +SCRATCH_DEV (SCRATCH_MNT) Group:
> + 1024 15 fsgqa
> +-n option
> +checking quot command (type=g)
> +SCRATCH_DEV (SCRATCH_MNT) Group:
> + 1024 15 #ID
> +
> +checking quota command (type=g)
> +Disk quotas for Group fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-f option
> +checking quota command (type=g)
> +Disk quotas for Group fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-N option
> +checking quota command (type=g)
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-n option
> +checking quota command (type=g)
> +Disk quotas for Group #ID (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-h option
> +checking quota command (type=g)
> +Disk quotas for Group fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +disable quota
> +
> +checking disable command (type=g)
> +Group quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: OFF
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [3 days]
> +Inodes grace time: [3 days]
> +Realtime Blocks grace time: [7 days]
> +
> +checking report command (type=g)
> +fsgqa 1024 512 2048 00 [--------] 15 10 20 00 [--------]
> +
> +expect a remove error at here
> +checking remove command (type=g)
> +XFS_QUOTARM: Invalid argument
> +
> +checking enable command (type=g)
> +Group quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: ON
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [3 days]
> +Inodes grace time: [3 days]
> +Realtime Blocks grace time: [7 days]
> +
> +checking report command (type=g)
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +off and remove test
> +
> +checking limit command (type=g, bsoft=100m, bhard=100m, isoft=100, ihard=100)
> +
> +checking quota command (type=g)
> +SCRATCH_DEV 1024 102400 102400 00 [--------] 15 100 100 00 [--------] SCRATCH_MNT
> +
> +checking off command (type=g)
> +Group quota are not enabled on SCRATCH_DEV
> +
> +checking state command (type=g)
> +
> +checking remove command (type=g)
> +Group quota are not enabled on SCRATCH_DEV
> +
> +checking report command (type=g)
> +
> +quota remount
> +
> +checking report command (type=g)
> +fsgqa 1024 0 0 00 [--------] 15 0 0 00 [--------]
> +
> +restore quota
> +
> +checking restore command (type=g)
> +
> +checking report command (type=g)
> +fsgqa 1024 512 2048 00 [7 days] 15 10 20 00 [7 days]
> +
> +
> +checking state command (type=g)
> +Group quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: ON
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [7 days]
> +Inodes grace time: [7 days]
> +Realtime Blocks grace time: [7 days]
> +cleanup files
> +----------------------- gquota,sync,idmapped ---------------------------
> +init quota limit and timer, and dump it
> +create_files_idmapped 1024k 15
> +quota remount
> +
> +checking quot command (type=g)
> +SCRATCH_DEV (SCRATCH_MNT) Group:
> + 1024 15 fsgqa
> +
> +checking timer command (type=g)
> +
> +checking limit command (type=g, bsoft=512k, bhard=2048k, isoft=10, ihard=20)
> +
> +checking dump command (type=g)
> +report options test
> +
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-N option
> +checking report command (type=g)
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-L -U options
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-t option
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-n option
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
> +---------- -------------------------------------------------- --------------------------------------------------
> +#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +-h option
> +checking report command (type=g)
> +Group quota on SCRATCH_MNT (SCRATCH_DEV)
> + Blocks Inodes
> +Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace
> +---------- --------------------------------- ---------------------------------
> +fsgqa 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days]
> +
> +quot options test
> +
> +checking quot command (type=g)
> +SCRATCH_DEV (SCRATCH_MNT) Group:
> + 1024 15 fsgqa
> +-f option
> +checking quot command (type=g)
> +SCRATCH_DEV (SCRATCH_MNT) Group:
> + 1024 15 fsgqa
> +-n option
> +checking quot command (type=g)
> +SCRATCH_DEV (SCRATCH_MNT) Group:
> + 1024 15 #ID
> +
> +checking quota command (type=g)
> +Disk quotas for Group fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-f option
> +checking quota command (type=g)
> +Disk quotas for Group fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-N option
> +checking quota command (type=g)
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-n option
> +checking quota command (type=g)
> +Disk quotas for Group #ID (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +-h option
> +checking quota command (type=g)
> +Disk quotas for Group fsgqa (ID)
> +Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
> +SCRATCH_DEV 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
> +disable quota
> +
> +checking disable command (type=g)
> +Group quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: OFF
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [3 days]
> +Inodes grace time: [3 days]
> +Realtime Blocks grace time: [7 days]
> +
> +checking report command (type=g)
> +fsgqa 1024 512 2048 00 [--------] 15 10 20 00 [--------]
> +
> +expect a remove error at here
> +checking remove command (type=g)
> +XFS_QUOTARM: Invalid argument
> +
> +checking enable command (type=g)
> +Group quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: ON
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [3 days]
> +Inodes grace time: [3 days]
> +Realtime Blocks grace time: [7 days]
> +
> +checking report command (type=g)
> +fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
> +
> +off and remove test
> +
> +checking limit command (type=g, bsoft=100m, bhard=100m, isoft=100, ihard=100)
> +
> +checking quota command (type=g)
> +SCRATCH_DEV 1024 102400 102400 00 [--------] 15 100 100 00 [--------] SCRATCH_MNT
> +
> +checking off command (type=g)
> +Group quota are not enabled on SCRATCH_DEV
> +
> +checking state command (type=g)
> +
> +checking remove command (type=g)
> +Group quota are not enabled on SCRATCH_DEV
> +
> +checking report command (type=g)
> +
> +quota remount
> +
> +checking report command (type=g)
> +fsgqa 1024 0 0 00 [--------] 15 0 0 00 [--------]
> +
> +restore quota
> +
> +checking restore command (type=g)
> +
> +checking report command (type=g)
> +fsgqa 1024 512 2048 00 [7 days] 15 10 20 00 [7 days]
> +
> +
> +checking state command (type=g)
> +Group quota state on SCRATCH_MNT (SCRATCH_DEV)
> + Accounting: ON
> + Enforcement: ON
> + Inode: #[INO] (X blocks, Y extents)
> +Blocks grace time: [7 days]
> +Inodes grace time: [7 days]
> +Realtime Blocks grace time: [7 days]
> +cleanup files
> diff --git a/tests/xfs/group b/tests/xfs/group
> index 288b916d..fb4599ca 100644
> --- a/tests/xfs/group
> +++ b/tests/xfs/group
> @@ -505,3 +505,4 @@
> 526 auto quick mkfs
> 527 auto quick quota
> 528 auto quick rw realtime
> +529 auto quick quota
> --
> 2.27.0
next prev parent reply other threads:[~2021-03-21 14:43 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-16 10:36 [PATCH v9 0/4 REBASED] fstests: add idmapped mounts tests Christian Brauner
2021-03-16 10:36 ` [PATCH v9 1/4] generic/631: add test for detached mount propagation Christian Brauner
2021-03-18 6:23 ` Christoph Hellwig
2021-03-18 15:02 ` Darrick J. Wong
2021-03-18 15:14 ` Christian Brauner
2021-03-18 15:57 ` Darrick J. Wong
2021-03-18 16:31 ` Darrick J. Wong
2021-03-21 14:28 ` Eryu Guan
2021-03-22 10:00 ` Christian Brauner
2021-03-16 10:36 ` [PATCH v9 3/4] xfs/529: quotas and idmapped mounts Christian Brauner
2021-03-18 6:24 ` Christoph Hellwig
2021-03-21 14:42 ` Eryu Guan [this message]
2021-03-22 10:11 ` Christian Brauner
2021-03-16 10:36 ` [PATCH v9 4/4] xfs/530: quotas on " Christian Brauner
2021-03-18 6:24 ` Christoph Hellwig
2021-03-21 14:51 ` Eryu Guan
2021-03-22 12:25 ` Christian Brauner
[not found] ` <20210316103627.2954121-3-christian.brauner@ubuntu.com>
2021-03-18 6:23 ` [PATCH v9 2/4] generic/632: add fstests for " Christoph Hellwig
2021-03-21 14:26 ` [PATCH v9 0/4 REBASED] fstests: add idmapped mounts tests Eryu Guan
2021-03-21 15:32 ` Christian Brauner
2021-03-22 2:37 ` Eryu Guan
2021-03-22 9:49 ` Christian Brauner
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=YFdbPtFPdyyZiL/F@desktop \
--to=guan@eryu.me \
--cc=christian.brauner@ubuntu.com \
--cc=dhowells@redhat.com \
--cc=djwong@kernel.org \
--cc=fstests@vger.kernel.org \
--cc=hch@lst.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).