diff options
author | наб <[email protected]> | 2022-03-12 04:30:22 +0100 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2022-04-01 17:58:17 -0700 |
commit | caeab993ec77ce15bcb25484017ff18f18a6550b (patch) | |
tree | ca2bcfa167e199e2317741f059cc54a25cde3f09 /tests/zfs-tests/cmd/linux_dos_attributes | |
parent | d30577c9dd811688f2609ad532b011b99bceb485 (diff) |
tests: {read,write}_dos_attributes: despaghettify
Also: actually accept all the flags in write_d_a
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: John Kennedy <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Closes #13259
Diffstat (limited to 'tests/zfs-tests/cmd/linux_dos_attributes')
5 files changed, 247 insertions, 0 deletions
diff --git a/tests/zfs-tests/cmd/linux_dos_attributes/.gitignore b/tests/zfs-tests/cmd/linux_dos_attributes/.gitignore new file mode 100644 index 000000000..14a62551d --- /dev/null +++ b/tests/zfs-tests/cmd/linux_dos_attributes/.gitignore @@ -0,0 +1,2 @@ +/read_dos_attributes +/write_dos_attributes diff --git a/tests/zfs-tests/cmd/linux_dos_attributes/Makefile.am b/tests/zfs-tests/cmd/linux_dos_attributes/Makefile.am new file mode 100644 index 000000000..2e383e94f --- /dev/null +++ b/tests/zfs-tests/cmd/linux_dos_attributes/Makefile.am @@ -0,0 +1,8 @@ +include $(top_srcdir)/config/Rules.am + +pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin + +EXTRA_DIST = dos_attributes.h +pkgexec_PROGRAMS = read_dos_attributes write_dos_attributes +read_dos_attributes_SOURCES = read_dos_attributes.c +write_dos_attributes_SOURCES = write_dos_attributes.c diff --git a/tests/zfs-tests/cmd/linux_dos_attributes/dos_attributes.h b/tests/zfs-tests/cmd/linux_dos_attributes/dos_attributes.h new file mode 100644 index 000000000..dd3a820ff --- /dev/null +++ b/tests/zfs-tests/cmd/linux_dos_attributes/dos_attributes.h @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: 0BSD + +#include <inttypes.h> + + +#define U_APPEND_SHORT "uappnd" +#define U_APPEND_FULL "uappend" +#define SU_APPEND_SHORT "sappnd" +#define SU_APPEND_FULL "sappend" + +#define U_ARCH_SHORT "uarch" +#define U_ARCH_FULL "uarchive" +#define SU_ARCH_SHORT "arch" +#define SU_ARCH_FULL "archived" + +#define U_HIDDEN_SHORT "hidden" +#define U_HIDDEN_FULL "uhidden" + +#define SU_IMMUTABLE_FULL "simmutable" +#define SU_IMMUTABLE_SHORT "schange" +#define SU_IMMUTABLE "schg" +#define U_IMMUTABLE_FULL "uimmutable" +#define U_IMMUTABLE_SHORT "uchange" +#define U_IMMUTABLE "uchg" + +#define SU_NODUMP "nodump" +#define UNSET_NODUMP "dump" + +#define U_UNLINK_SHORT "uunlnk" +#define U_UNLINK_FULL "uunlink" +#define SU_UNLINK_SHORT "sunlnk" +#define SU_UNLINK_FULL "sunlink" + +#define U_OFFLINE_SHORT "offline" +#define U_OFFLINE_FULL "uoffline" + +#define U_RDONLY "rdonly" +#define U_RDONLY_SHORT "urdonly" +#define U_RDONLY_FULL "readonly" + +#define U_REPARSE_SHORT "reparse" +#define U_REPARSE_FULL "ureparse" + +#define U_SPARSE_SHORT "sparse" +#define U_SPARSE_FULL "usparse" + +#define U_SYSTEM_SHORT "system" +#define U_SYSTEM_FULL "usystem" + + +static const uint64_t all_dos_attributes[] = { + ZFS_ARCHIVE, + ZFS_APPENDONLY, + ZFS_IMMUTABLE, + ZFS_NOUNLINK, + ZFS_NODUMP, + ZFS_HIDDEN, + ZFS_OFFLINE, + ZFS_READONLY, + ZFS_SPARSE, + ZFS_SYSTEM, + ZFS_REPARSE, +}; + +static const char *const all_dos_attribute_names[][7] = { + {U_ARCH_SHORT, U_ARCH_FULL, SU_ARCH_SHORT, SU_ARCH_FULL}, + {U_APPEND_SHORT, U_APPEND_FULL, SU_APPEND_SHORT, SU_APPEND_FULL}, + {SU_IMMUTABLE_FULL, SU_IMMUTABLE_SHORT, SU_IMMUTABLE, + U_IMMUTABLE_FULL, U_IMMUTABLE_SHORT, U_IMMUTABLE}, + {U_UNLINK_SHORT, U_UNLINK_FULL, SU_UNLINK_FULL, SU_UNLINK_SHORT}, + {SU_NODUMP, /* UNSET_NODUMP */}, + {U_HIDDEN_SHORT, U_HIDDEN_FULL}, + {U_OFFLINE_SHORT, U_OFFLINE_FULL}, + {U_RDONLY, U_RDONLY_SHORT, U_RDONLY_FULL}, + {U_SPARSE_SHORT, U_SPARSE_FULL}, + {U_SYSTEM_SHORT, U_SYSTEM_FULL}, + {U_REPARSE_SHORT, U_REPARSE_FULL}, +}; + +_Static_assert( + ARRAY_SIZE(all_dos_attributes) == ARRAY_SIZE(all_dos_attribute_names), + "attribute list length mismatch"); diff --git a/tests/zfs-tests/cmd/linux_dos_attributes/read_dos_attributes.c b/tests/zfs-tests/cmd/linux_dos_attributes/read_dos_attributes.c new file mode 100644 index 000000000..078211405 --- /dev/null +++ b/tests/zfs-tests/cmd/linux_dos_attributes/read_dos_attributes.c @@ -0,0 +1,60 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2022 iXsystems, Inc. + */ + +/* + * FreeBSD exposes additional file attributes via ls -o and chflags. + * Under Linux, we provide ZFS_IOC_[GS]ETDOSFLAGS ioctl()s. + * + * This application is the equivalent to FreeBSD ls -lo $1 | awk '{print $5}'. + */ + +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/fs/zfs.h> +#include "dos_attributes.h" + +int +main(int argc, const char *const *argv) +{ + if (argc != 2) + errx(EXIT_FAILURE, "usage: %s file", argv[0]); + + int fd = open(argv[1], O_RDONLY | O_CLOEXEC); + if (fd == -1) + err(EXIT_FAILURE, "%s", argv[1]); + + uint64_t flags; + if (ioctl(fd, ZFS_IOC_GETDOSFLAGS, &flags) == -1) + err(EXIT_FAILURE, "ZFS_IOC_GETDOSFLAGS"); + + bool any = false; + for (size_t i = 0; i < ARRAY_SIZE(all_dos_attributes); ++i) + if (flags & all_dos_attributes[i]) { + if (any) + putchar(','); + (void) fputs(*all_dos_attribute_names[i], stdout); + any = true; + } + if (any) + (void) putchar('\n'); + else + (void) puts("-"); +} diff --git a/tests/zfs-tests/cmd/linux_dos_attributes/write_dos_attributes.c b/tests/zfs-tests/cmd/linux_dos_attributes/write_dos_attributes.c new file mode 100644 index 000000000..3cea7d4b1 --- /dev/null +++ b/tests/zfs-tests/cmd/linux_dos_attributes/write_dos_attributes.c @@ -0,0 +1,95 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2022 iXsystems, Inc. + */ + +/* + * FreeBSD exposes additional file attributes via ls -o and chflags. + * Under Linux, we provide ZFS_IOC_[GS]ETDOSFLAGS ioctl()s. + * + * This application is equivalent to FreeBSD chflags. + */ + +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/fs/zfs.h> +#include "dos_attributes.h" + +int +main(int argc, const char *const *argv) +{ + if (argc != 3) + errx(EXIT_FAILURE, "usage: %s flag file", argv[0]); + + bool unset = false; + uint64_t attr = 0; + const char *flag = argv[1]; + if (strcmp(flag, "0") == 0) + ; + else if (strcmp(flag, SU_NODUMP) == 0) + attr = ZFS_NODUMP; + else if (strcmp(flag, UNSET_NODUMP) == 0) { + attr = ZFS_NODUMP; + unset = true; + } else { + if (strncmp(flag, "no", 2) == 0) { + unset = true; + flag += 2; + } + for (size_t i = 0; i < ARRAY_SIZE(all_dos_attribute_names); ++i) + for (const char *const *nm = all_dos_attribute_names[i]; + *nm; ++nm) + if (strcmp(flag, *nm) == 0) { + attr = all_dos_attributes[i]; + goto found; + } + + errx(EXIT_FAILURE, "%s: unknown flag", argv[1]); +found:; + } + + int fd = open(argv[2], O_RDWR | O_APPEND | O_CLOEXEC); + if (fd == -1) + err(EXIT_FAILURE, "%s", argv[2]); + + uint64_t flags; + if (ioctl(fd, ZFS_IOC_GETDOSFLAGS, &flags) == -1) + err(EXIT_FAILURE, "ZFS_IOC_GETDOSFLAGS"); + + if (attr == 0) + flags = 0; + else if (unset) + flags &= ~attr; + else + flags |= attr; + + if (ioctl(fd, ZFS_IOC_SETDOSFLAGS, &flags) == -1) + err(EXIT_FAILURE, "ZFS_IOC_SETDOSFLAGS"); + + uint64_t newflags; + if (ioctl(fd, ZFS_IOC_GETDOSFLAGS, &newflags) == -1) + err(EXIT_FAILURE, "second ZFS_IOC_GETDOSFLAGS"); + + if (newflags != flags) + errx(EXIT_FAILURE, "expecting %#" PRIx64 ", got %#" PRIx64 + "; %ssetting %#" PRIx64 "", + flags, newflags, unset ? "un" : "", attr); + + (void) printf("%#" PRIx64 "\n", flags); +} |