xref: /netbsd-src/tests/fs/ffs/t_extattr.c (revision 87ba0e2a319653af510fae24a6d2975d3589735b)
1*87ba0e2aSchs /*	$NetBSD: t_extattr.c,v 1.3 2022/11/17 06:40:40 chs Exp $	*/
234f2ea29Schristos 
334f2ea29Schristos /*-
434f2ea29Schristos  * Copyright (c) 2020 The NetBSD Foundation, Inc.
534f2ea29Schristos  * All rights reserved.
634f2ea29Schristos  *
734f2ea29Schristos  * This code is derived from software contributed to The NetBSD Foundation
834f2ea29Schristos  * by Christos Zoulas.
934f2ea29Schristos  *
1034f2ea29Schristos  * Redistribution and use in source and binary forms, with or without
1134f2ea29Schristos  * modification, are permitted provided that the following conditions
1234f2ea29Schristos  * are met:
1334f2ea29Schristos  * 1. Redistributions of source code must retain the above copyright
1434f2ea29Schristos  *    notice, this list of conditions and the following disclaimer.
1534f2ea29Schristos  * 2. Redistributions in binary form must reproduce the above copyright
1634f2ea29Schristos  *    notice, this list of conditions and the following disclaimer in the
1734f2ea29Schristos  *    documentation and/or other materials provided with the distribution.
1834f2ea29Schristos  *
1934f2ea29Schristos  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2034f2ea29Schristos  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2134f2ea29Schristos  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2234f2ea29Schristos  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2334f2ea29Schristos  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2434f2ea29Schristos  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2534f2ea29Schristos  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2634f2ea29Schristos  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2734f2ea29Schristos  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2834f2ea29Schristos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2934f2ea29Schristos  * POSSIBILITY OF SUCH DAMAGE.
3034f2ea29Schristos  */
3134f2ea29Schristos #include <sys/cdefs.h>
32*87ba0e2aSchs __RCSID("$NetBSD: t_extattr.c,v 1.3 2022/11/17 06:40:40 chs Exp $");
3334f2ea29Schristos 
3434f2ea29Schristos #include <sys/types.h>
3534f2ea29Schristos #include <sys/mount.h>
3634f2ea29Schristos #include <sys/extattr.h>
3734f2ea29Schristos 
3834f2ea29Schristos #include <atf-c.h>
3934f2ea29Schristos #include <errno.h>
4034f2ea29Schristos #include <fcntl.h>
4134f2ea29Schristos #include <pthread.h>
4234f2ea29Schristos #include <stdio.h>
4334f2ea29Schristos #include <stdlib.h>
4434f2ea29Schristos #include <unistd.h>
4534f2ea29Schristos #include <string.h>
4634f2ea29Schristos 
4734f2ea29Schristos #include <rump/rump.h>
4834f2ea29Schristos #include <rump/rump_syscalls.h>
4934f2ea29Schristos 
5034f2ea29Schristos #include <ufs/ufs/ufsmount.h>
5134f2ea29Schristos 
5234f2ea29Schristos #include "h_macros.h"
5334f2ea29Schristos 
5434f2ea29Schristos #define IMGNAME "extattr.img"
5534f2ea29Schristos 
5634f2ea29Schristos #define G "/garage"
5734f2ea29Schristos #define M "mercedes"
5834f2ea29Schristos #define C "carburator"
5934f2ea29Schristos #define E "engine"
6034f2ea29Schristos #define T "trunk"
6134f2ea29Schristos #define S "suitcase"
6234f2ea29Schristos 
6334f2ea29Schristos static const char *attrs[] = { E, T };
6434f2ea29Schristos 
6534f2ea29Schristos static void
check_list(const char * buf,ssize_t nr)6634f2ea29Schristos check_list(const char *buf, ssize_t nr)
6734f2ea29Schristos {
6834f2ea29Schristos 	size_t p = 0;
6934f2ea29Schristos 	for (size_t i = 0; i < __arraycount(attrs); i++) {
7034f2ea29Schristos 		size_t l = buf[p++];
7134f2ea29Schristos 		if (l != strlen(attrs[i]))
7234f2ea29Schristos 		    atf_tc_fail("got invalid len %zu expected %zu", l,
7334f2ea29Schristos 			strlen(attrs[i]));
7434f2ea29Schristos 		if (strncmp(&buf[p], attrs[i], l) != 0)
7534f2ea29Schristos 			atf_tc_fail("got invalid str %.*s expected %s", (int)l,
7634f2ea29Schristos 			    &buf[p], attrs[i]);
7734f2ea29Schristos 		p += l;
7834f2ea29Schristos 	}
7934f2ea29Schristos }
8034f2ea29Schristos 
81*87ba0e2aSchs // Make it ffsv2 with extattrs
82*87ba0e2aSchs const char *newfs = "newfs -O 2ea -F -s 10000 " IMGNAME;
8334f2ea29Schristos #define FAKEBLK "/dev/formula1"
8434f2ea29Schristos 
8597cf9247Schristos static void
start(void)8697cf9247Schristos start(void) {
8734f2ea29Schristos 	struct ufs_args args;
8834f2ea29Schristos 
8934f2ea29Schristos 	if (system(newfs) == -1)
9034f2ea29Schristos 		atf_tc_fail_errno("newfs failed");
9134f2ea29Schristos 
9234f2ea29Schristos 	memset(&args, 0, sizeof(args));
9334f2ea29Schristos 	args.fspec = __UNCONST(FAKEBLK);
9434f2ea29Schristos 
9534f2ea29Schristos 	rump_init();
9634f2ea29Schristos 	if (rump_sys_mkdir(G, 0777) == -1)
9734f2ea29Schristos 		atf_tc_fail_errno("cannot create mountpoint");
9834f2ea29Schristos 	rump_pub_etfs_register(FAKEBLK, IMGNAME, RUMP_ETFS_BLK);
9934f2ea29Schristos 	if (rump_sys_mount(MOUNT_FFS, G, 0, &args, sizeof(args))==-1)
10034f2ea29Schristos 		atf_tc_fail_errno("rump_sys_mount failed");
10134f2ea29Schristos 
10234f2ea29Schristos 	/* create extattr */
10334f2ea29Schristos 	if (rump_sys_chdir(G) == 1)
10434f2ea29Schristos 		atf_tc_fail_errno("chdir");
10597cf9247Schristos }
10697cf9247Schristos 
10797cf9247Schristos static void
finish(void)10897cf9247Schristos finish(void) {
10997cf9247Schristos 	if (rump_sys_chdir("/") == 1)
11097cf9247Schristos 		atf_tc_fail_errno("chdir");
11197cf9247Schristos 	if (rump_sys_unmount(G, 0) == -1)
11297cf9247Schristos 		atf_tc_fail_errno("unmount failed");
11397cf9247Schristos }
11497cf9247Schristos 
11597cf9247Schristos 
11697cf9247Schristos ATF_TC_WITH_CLEANUP(extattr_simple);
ATF_TC_HEAD(extattr_simple,tc)11797cf9247Schristos ATF_TC_HEAD(extattr_simple, tc)
11897cf9247Schristos {
11997cf9247Schristos 	atf_tc_set_md_var(tc, "descr", "test extended attribute creation"
12097cf9247Schristos 	    " and removal ffsv2");
12197cf9247Schristos 	atf_tc_set_md_var(tc, "timeout", "5");
12297cf9247Schristos }
12397cf9247Schristos 
ATF_TC_BODY(extattr_simple,tc)12497cf9247Schristos ATF_TC_BODY(extattr_simple, tc)
12597cf9247Schristos {
12697cf9247Schristos 	ssize_t nr;
12797cf9247Schristos 	int fd;
12897cf9247Schristos 	char buf[512];
12997cf9247Schristos 
13097cf9247Schristos 	start();
13197cf9247Schristos 
13234f2ea29Schristos 	if ((fd = rump_sys_open(M, O_RDWR | O_CREAT, 0600)) == -1)
13334f2ea29Schristos 		atf_tc_fail_errno("open");
13434f2ea29Schristos 	if (rump_sys_write(fd, "hi mom\n", 7) != 7)
13534f2ea29Schristos 		atf_tc_fail_errno("write");
13634f2ea29Schristos 
13734f2ea29Schristos 	if (rump_sys_extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, E, C, 11) == -1)
13834f2ea29Schristos 		atf_tc_fail_errno("exattr_set_fd");
13934f2ea29Schristos 	if ((nr = rump_sys_extattr_get_file(M, EXTATTR_NAMESPACE_USER,
14034f2ea29Schristos 	    E, buf, sizeof(buf))) != 11)
14134f2ea29Schristos 		atf_tc_fail_errno("extattr_get_file");
14234f2ea29Schristos 	if (strcmp(buf, C) != 0)
14334f2ea29Schristos 		atf_tc_fail("got invalid str %s expected %s", buf, C);
14434f2ea29Schristos 
14534f2ea29Schristos 	if (rump_sys_extattr_set_file(M, EXTATTR_NAMESPACE_USER, T, S, 9) == -1)
14634f2ea29Schristos 		atf_tc_fail_errno("extattr_set_file");
14734f2ea29Schristos 	if ((nr = rump_sys_extattr_get_fd(fd, EXTATTR_NAMESPACE_USER,
14834f2ea29Schristos 	    T, buf, sizeof(buf))) != 9)
14934f2ea29Schristos 		atf_tc_fail_errno("extattr_get_fd");
15034f2ea29Schristos 	if (strcmp(buf, S) != 0)
15134f2ea29Schristos 		atf_tc_fail("got invalid str %s expected %s", buf, S);
15234f2ea29Schristos 
15334f2ea29Schristos 	if ((nr = rump_sys_extattr_list_fd(fd, EXTATTR_NAMESPACE_USER,
15434f2ea29Schristos 	    buf, sizeof(buf))) != 13)
15534f2ea29Schristos 		atf_tc_fail_errno("extattr_list_fd %zd", nr);
15634f2ea29Schristos 	check_list(buf, __arraycount(attrs));
15734f2ea29Schristos 
15834f2ea29Schristos 	if ((nr = rump_sys_extattr_list_file(M, EXTATTR_NAMESPACE_USER,
15934f2ea29Schristos 	    buf, sizeof(buf))) != 13)
16034f2ea29Schristos 		atf_tc_fail_errno("extattr_list_file %zd", nr);
16134f2ea29Schristos 	check_list(buf, __arraycount(attrs));
16234f2ea29Schristos 
16334f2ea29Schristos 	if (rump_sys_extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, T) == -1)
16434f2ea29Schristos 		atf_tc_fail_errno("extattr_delete_fd");
16534f2ea29Schristos 	if ((nr = rump_sys_extattr_list_fd(fd, EXTATTR_NAMESPACE_USER,
16634f2ea29Schristos 	    buf, sizeof(buf))) != 7)
16734f2ea29Schristos 		atf_tc_fail_errno("extattr_list_fd %zd", nr);
16834f2ea29Schristos 	check_list(buf, 1);
16934f2ea29Schristos 
17034f2ea29Schristos 	if (rump_sys_extattr_delete_file(M, EXTATTR_NAMESPACE_USER, E) == -1)
17134f2ea29Schristos 		atf_tc_fail_errno("extattr_delete_file");
17234f2ea29Schristos 	if ((nr = rump_sys_extattr_list_fd(fd, EXTATTR_NAMESPACE_USER,
17334f2ea29Schristos 	    buf, sizeof(buf))) != 0)
17434f2ea29Schristos 		atf_tc_fail_errno("extattr_list_fd %zd", nr);
17534f2ea29Schristos 
17634f2ea29Schristos 	if (rump_sys_close(fd) == -1)
17734f2ea29Schristos 		atf_tc_fail_errno("close");
17834f2ea29Schristos 	if (rump_sys_unlink(M) == -1)
17934f2ea29Schristos 		atf_tc_fail_errno("unlink");
18097cf9247Schristos 
18197cf9247Schristos 	finish();
18234f2ea29Schristos }
18334f2ea29Schristos 
ATF_TC_CLEANUP(extattr_simple,tc)18497cf9247Schristos ATF_TC_CLEANUP(extattr_simple, tc)
18597cf9247Schristos {
18697cf9247Schristos 
18797cf9247Schristos 	unlink(IMGNAME);
18897cf9247Schristos }
18997cf9247Schristos 
19097cf9247Schristos ATF_TC_WITH_CLEANUP(extattr_create_unlink);
ATF_TC_HEAD(extattr_create_unlink,tc)19197cf9247Schristos ATF_TC_HEAD(extattr_create_unlink, tc)
19297cf9247Schristos {
19397cf9247Schristos 	atf_tc_set_md_var(tc, "descr", "test extended attribute creation"
19497cf9247Schristos 	    " and unlinking file with ACLs");
19597cf9247Schristos 	atf_tc_set_md_var(tc, "timeout", "5");
19697cf9247Schristos }
19797cf9247Schristos 
ATF_TC_BODY(extattr_create_unlink,tc)19897cf9247Schristos ATF_TC_BODY(extattr_create_unlink, tc)
19997cf9247Schristos {
20097cf9247Schristos 	int fd;
20197cf9247Schristos 
20297cf9247Schristos 	start();
20397cf9247Schristos 	if ((fd = rump_sys_open(M, O_RDWR | O_CREAT, 0600)) == -1)
20497cf9247Schristos 		atf_tc_fail_errno("open");
20597cf9247Schristos 
20697cf9247Schristos 	if (rump_sys_close(fd) == -1)
20797cf9247Schristos 		atf_tc_fail_errno("close");
20897cf9247Schristos 
20997cf9247Schristos 	/* create extattr */
21097cf9247Schristos 	if (rump_sys_extattr_set_file(M, EXTATTR_NAMESPACE_USER, T, S, 9) == -1)
21197cf9247Schristos 		atf_tc_fail_errno("extattr_set_file");
21297cf9247Schristos 
21397cf9247Schristos 	if (rump_sys_unlink(M) == -1)
21497cf9247Schristos 		atf_tc_fail_errno("unlink");
21597cf9247Schristos 	finish();
21697cf9247Schristos 
21797cf9247Schristos }
21897cf9247Schristos 
ATF_TC_CLEANUP(extattr_create_unlink,tc)21997cf9247Schristos ATF_TC_CLEANUP(extattr_create_unlink, tc)
22034f2ea29Schristos {
22134f2ea29Schristos 
22234f2ea29Schristos 	unlink(IMGNAME);
22334f2ea29Schristos }
22434f2ea29Schristos 
ATF_TP_ADD_TCS(tp)22534f2ea29Schristos ATF_TP_ADD_TCS(tp)
22634f2ea29Schristos {
22797cf9247Schristos 	ATF_TP_ADD_TC(tp, extattr_simple);
22897cf9247Schristos 	ATF_TP_ADD_TC(tp, extattr_create_unlink);
22934f2ea29Schristos 	return atf_no_error();
23034f2ea29Schristos }
231