From 2e5e3e4b18fbe4cabce5948cedb4b4e6d90714ac Mon Sep 17 00:00:00 2001 From: Filipe Brandenburger Date: Wed, 27 Aug 2014 04:30:00 +0400 Subject: [PATCH] zdtm: fallback to mknod(/dev/ptmx) when CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set A kernel without that option configured does not have /dev/pts/ptmx, so fallback to the previous way of creating it using mknod instead. The previous code was trying to bind mount ptmx on top of a symlink, which does not actually work... Keep only the symlink call and use a relative symlink instead. Adjust the error message of the symlink case to mention symlink() instead of mknod() and also /dev/ptmx instead of /dev/pts. Tested: - zdtm test suite runs on ^ns/static/.* before and after the change. - Same on a kernel with CONFIG_DEVPTS_MULTIPLE_INSTANCES unset. Signed-off-by: Filipe Brandenburger Acked-by: Andrew Vagin Signed-off-by: Pavel Emelyanov --- test/zdtm/lib/ns.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/test/zdtm/lib/ns.c b/test/zdtm/lib/ns.c index 8afec5bdf..40e7005d7 100644 --- a/test/zdtm/lib/ns.c +++ b/test/zdtm/lib/ns.c @@ -72,18 +72,27 @@ static int prepare_mntns() fprintf(stderr, "mkdir(/dev/pts) failed: %m\n"); return -1; } - if (symlink("/dev/pts/ptmx", "/dev/ptmx") && errno != EEXIST) { - fprintf(stderr, "mknod(/dev/ptmx) failed: %m\n"); - return -1; - } - chmod("/dev/ptmx", 0666); if (mount("pts", "/dev/pts", "devpts", MS_MGC_VAL, "mode=666,ptmxmode=666,newinstance")) { fprintf(stderr, "mount(/dev/pts) failed: %m\n"); return -1; } - if (mount("/dev/pts/ptmx", "/dev/ptmx", NULL, MS_BIND, NULL)) { - fprintf(stderr, "mount(/dev/pts) failed: %m\n"); - return -1; + /* + * If CONFIG_DEVPTS_MULTIPLE_INSTANCES=n, then /dev/pts/ptmx + * does not exist. Fall back to creating the device with + * mknod() in that case. + */ + if (access("/dev/pts/ptmx", F_OK) == 0) { + if (symlink("pts/ptmx", "/dev/ptmx") && errno != EEXIST) { + fprintf(stderr, "symlink(/dev/ptmx) failed: %m\n"); + return -1; + } + } else { + if (mknod("/dev/ptmx", 0666 | S_IFCHR, makedev(5, 2)) == 0) { + chmod("/dev/ptmx", 0666); + } else if (errno != EEXIST) { + fprintf(stderr, "mknod(/dev/ptmx) failed: %m\n"); + return -1; + } } if (fchdir(dfd)) { fprintf(stderr, "fchdir() failed: %m\n");