zdtm: add a test on open symlink migration

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Co-Developed-by: Vitaly Ostrosablin <vostrosablin@virtuozzo.com>
Signed-off-by: Vitaly Ostrosablin <vostrosablin@virtuozzo.com>
Signed-off-by: Alexander Mikhalitsyn (Virtuozzo) <alexander@mihalicyn.com>
This commit is contained in:
Pavel Tikhomirov 2020-02-07 16:00:05 +03:00 committed by Andrei Vagin
parent 1936608ce4
commit 73e0ed3b8a
4 changed files with 107 additions and 1 deletions

View file

@ -364,6 +364,8 @@ TST_DIR = \
ghost_on_rofs \
overmounted_file \
opath_file \
symlink \
symlink01 \
TST_DIR_FILE = \
chroot \
@ -539,6 +541,7 @@ clone_fs: LDLIBS += -pthread
# we have to explicitly specify both .o and .d for this case:
netns_sub_veth.o netns_sub_veth.d: CPPFLAGS += $(call pkg-cflags, libnl-3.0)
netns_sub_veth: LDLIBS += $(call pkg-libs, libnl-route-3.0 libnl-3.0)
symlink01: CFLAGS += -DZDTM_UNLINK_SYMLINK
socket-tcp-fin-wait1: CFLAGS += -D ZDTM_TCP_FIN_WAIT1
socket-tcp-fin-wait2: CFLAGS += -D ZDTM_TCP_FIN_WAIT2

View file

@ -36,7 +36,7 @@ static int parse_self_fdinfo(int fd, struct fdinfo *fi)
while (fgets(line, sizeof(line), file)) {
if (fdinfo_field(line, "flags")) {
if (sscanf(line, "%*s %llu", &val) != 1) {
if (sscanf(line, "%*s %llo", &val) != 1) {
pr_err("failed to read flags: %s", line);
goto fail;
}

102
test/zdtm/static/symlink.c Normal file
View file

@ -0,0 +1,102 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <limits.h>
#include "zdtmtst.h"
#define TEST_FILE "test_file"
#define TEST_SYMLINK "test_symlink"
const char *test_doc = "Check open symlink preserved";
const char *test_author = "Pavel Tikhomirov <ptikhomirov@virtuozzo.com>";
char *dirname;
TEST_OPTION(dirname, string, "directory name", 1);
int main(int argc, char **argv)
{
char test_symlink[PATH_MAX];
char test_file[PATH_MAX];
char pathbuf[PATH_MAX];
struct stat stb, sta;
int ret, fd;
test_init(argc, argv);
if (mkdir(dirname, 0700)) {
pr_perror("can't make directory %s", dirname);
exit(1);
}
snprintf(test_file, sizeof(test_file), "%s/%s", dirname, TEST_FILE);
ret = creat(test_file, 0644);
if (ret == -1) {
pr_perror("cat't create %s", test_file);
return 1;
}
close(ret);
snprintf(test_symlink, sizeof(test_symlink), "%s/%s", dirname, TEST_SYMLINK);
ret = symlink(test_file, test_symlink);
if (ret == -1) {
pr_perror("cat't symlink to %s", test_symlink);
return 1;
}
fd = open(test_symlink, O_PATH | O_NOFOLLOW);
if (fd == -1) {
pr_perror("cat't open symlink %s", test_symlink);
return 1;
}
ret = fstat(fd, &sta);
if (ret == -1) {
pr_perror("cat't fstat %s", test_symlink);
return 1;
}
if (!S_ISLNK(sta.st_mode)) {
pr_perror("file is not symlink %s", test_symlink);
return 1;
}
#ifdef ZDTM_UNLINK_SYMLINK
if (unlink(test_symlink)) {
pr_perror("can't unlink symlink %s", test_symlink);
return 1;
}
#endif
test_daemon();
test_waitsig();
ret = fstat(fd, &stb);
if (ret == -1) {
fail("cat't fstat %s", test_symlink);
return 1;
}
if (!S_ISLNK(stb.st_mode)) {
fail("file is not symlink %s", test_symlink);
return 1;
}
ret = readlinkat(fd, "", pathbuf, sizeof(pathbuf) - 1);
if (ret < 0) {
fail("Can't readlinkat");
return 1;
}
pathbuf[ret] = 0;
if (strcmp(test_file, pathbuf)) {
fail("symlink points to %s but %s expected", pathbuf, test_file);
return 1;
}
close(fd);
pass();
return 0;
}

View file

@ -0,0 +1 @@
symlink.c