Thanks Gowri for this Patch. I would however require posting of the
results on running these tests on a NETNS enabled kernel. Probably you
or Sudhir or Veerendra can provide me that once the patch series are
reviewed and ACK-ed completely.
Regards--
Subrata
On Fri, 2008-08-22 at 17:59 +0530, Gowrishankar M wrote:
> Hi Subrata,
> Please find below the test case for network namespace to check the
> functionality of tcp "echo" service.
>
> Signed-off-by: Gowrishankar Muthukrishnan <[EMAIL PROTECTED]>
>
> Index: b/testcases/kernel/containers/netns/tcp_cmds/echo/Makefile
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ b/testcases/kernel/containers/netns/tcp_cmds/echo/Makefile
> 2008-08-22 17:49:24.000000000 +0530
> @@ -0,0 +1,40 @@
> +################################################################################
> +##
>
> ##
> +## Copyright (c) International Business Machines Corp.,
> 2007 ##
> +##
>
> ##
> +## This program is free software; you can redistribute it and#or
> modify ##
> +## it under the terms of the GNU General Public License as published
> by ##
> +## the Free Software Foundation; either version 2 of the License,
> or ##
> +## (at your option) any later
> version. ##
> +##
>
> ##
> +## This program is distributed in the hope that it will be useful,
> but ##
> +## WITHOUT ANY WARRANTY; without even the implied warranty of
> MERCHANTABILITY ##
> +## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
> License ##
> +## for more
> details. ##
> +##
>
> ##
> +## You should have received a copy of the GNU General Public
> License ##
> +## along with this program; if not, write to the Free
> Software ##
> +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
> USA ##
> +##
>
> ##
> +################################################################################
> +
> +CFLAGS += -Wall -g
> +CPPFLAGS += -I../../../../../../include -I../../../libclone
> +LDLIBS += -L../../../../../../lib -L../../../libclone
> ../../../libclone/libclone.a -lltp
> +
> +SRCS = $(wildcard *.c)
> +TARGETS = $(patsubst %.c,%,$(SRCS))
> +NOLTP_TARGETS = $(patsubst %.c,%_noltp,$(NOLTPSRCS))
> +
> +
> +%_noltp : %.c
> + $(CC) -g -DNO_LTP -o $@ $< ../../../libclone/libclone.a
> +
> +all: $(TARGETS)
> +
> +install:
> + @set -e; for i in $(TARGETS) ; do ln -f $$i ../../../../../bin/$$i
> ; done
> +noltp: $(NOLTP_TARGETS)
> +
> +clean:
> + rm -f $(TARGETS) *.o $(NOLTP_TARGETS)
> Index: b/testcases/kernel/containers/netns/tcp_cmds/echo/echoc01.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ b/testcases/kernel/containers/netns/tcp_cmds/echo/echoc01.c
> 2008-08-22 17:48:59.000000000 +0530
> @@ -0,0 +1,448 @@
> +/*
> + *
> + * Copyright (c) International Business Machines Corp., 2001
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
> + * the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
> 02111-1307 USA
> + */
> +
> +/*
> + * Test Name: echoc01
> + *
> + * Test Description:
> + * This test checks echo(tcp) service functionality in parent and child
> + * network namespaces.
> + * Objective of the test is that, after parent and child put some data in
> + * the port of echo service (tcp), same data should be readback, while
> + * both are running echo service at the same time.
> + *
> + * Usage: <for command-line>
> + * echoc01
> + *
> + * HISTORY
> + * 21/2008 Gowrishankar Muthukrishnan([EMAIL PROTECTED]) Creation
> + *
> + * RESTRICTIONS:
> + * None.
> + *
> + */
> +
> +/* Standard include files */
> +#include <arpa/inet.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <netdb.h>
> +#include <sched.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/select.h>
> +#include <sys/socket.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +#include <unistd.h>
> +
> +/* User defined include files */
> +#include "libclone.h"
> +
> +/* Harness specific include files */
> +#ifndef NOLTP
> +#include "test.h"
> +#include "usctest.h"
> +#endif
> +
> +#ifndef BUFFER_SIZE
> +#define BUFFER_SIZE 200
> +#endif
> +
> +extern int Tst_count;
> +extern char *TESTDIR;
> +char *TCID = "echoc01";
> +int TST_TOTAL = 1;
> +
> +extern int errno;
> +extern int h_errno;
> +void do_setup(void);
> +void do_cleanup(void);
> +int do_parent_setup(void *);
> +int do_child_setup(void *);
> +int do_connect_socket();
> +void do_close_socket(int);
> +int do_echofile(int, char*);
> +int do_read_from_echo(int, int, char*);
> +
> +/* Common cleanup */
> +void do_cleanup(void)
> +{
> + system("/etc/init.d/xinetd stop 1>/dev/null");
> + system("rm -f /tmp/FIFO-sync");
> + system("rm -f /tmp/echoc01-xinetd-p.pid /tmp/echoc01-xinetd-c.pid");
> +}
> +
> +/* Common setup */
> +void do_setup(void)
> +{
> + int fd;
> + char line[80];
> + do_cleanup();
> + system("rm -f echoc01-parent.dat* echoc01-child.dat*");
> + system("mkfifo /tmp/FIFO-sync");
> + fd = creat("echoc01-parent.dat", S_IRWXU|S_IRWXG|S_IROTH);
> + if (fd < 0) {
> + tst_brkm(TBROK, do_cleanup,
> + "failed to create data file echoc01-parent.dat");
> + }
> + sprintf(line, "%s",\
> + "AAAAAAAABBBBBSSS1111111222&&&&&&UUUUUNNNNNNNN\n\0");
> + write(fd, line, strlen(line));
> + close(fd);
> + fd = creat("echoc01-child.dat", S_IRWXU|S_IRWXG|S_IROTH);
> + if (fd < 0) {
> + tst_brkm(TBROK, do_cleanup,
> + "failed to create data file echoc01-child.dat");
> + }
> + sprintf(line, "%s",\
> + "HHHHHDDDDDDD^^6666666633333333332222222QQQQQ\n\0");
> + write(fd, line, strlen(line));
> + close(fd);
> +}
> +
> +/* Setup specific to parent process */
> +int do_parent_setup(void *file)
> +{
> + int pid, ret, sd;
> + int bytes;
> + char *newfile;
> + char command[80];
> + pid = getpid();
> +
> + /* Activate loopback interface */
> + if (system("ifconfig lo up") != 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: activating loopback failed\n", pid);
> + tst_resm(TINFO, "%d: activated loopback.", pid);
> +
> + /* Activate echo service */
> + if (system("xinetd -pidfile /tmp/echoc01-xinetd-p.pid \
> + -stayalive -inetd_compat") != 0) {
> + tst_resm(TBROK, "%d: activating xinetd failed\n", pid);
> + return 1;
> + }
> + tst_resm(TINFO, "%d: activated xinetd services.", pid);
> +
> + /* Create a socket and connect it to echo service */
> + sd = do_connect_socket();
> + tst_resm(TINFO, "%d: parent has connected socket", pid);
> +
> + /* Wait for child process to have xinetd activated (stage 1) */
> + system("echo sync stage 1 > /tmp/FIFO-sync");
> +
> + /* Write data in socket connected to echo service */
> + bytes = do_echofile(sd, file);
> + tst_resm(TINFO, "%d: parent has written into echo port.", pid);
> +
> + /* Wait for child to have its socket connected (stage 2) */
> + system("cat /tmp/FIFO-sync > /dev/null");
> +
> + /* Wait for child to write data on its socket (stage 3) */
> + system("echo sync stage 3 > /tmp/FIFO-sync");
> +
> + /* Read data that is being echoed */
> + newfile = malloc(strlen(file) + 1);
> + newfile = memcpy(newfile, file, strlen(file)+1);
> + newfile = strcat(newfile, ".echo");
> + ret = do_read_from_echo(sd, bytes, newfile);
> + tst_resm(TINFO, "%d: parent has readback from echo.", pid);
> +
> + /* Close sockets and perform cleanup */
> + do_close_socket(sd);
> + do_cleanup();
> +
> + /* Validate the data that is echoed */
> + sprintf(command, "cmp -s %s %s", (char *)file, newfile);
> + if (system(command) == 0)
> + tst_resm(TPASS, "%s(PARENT) passed.", TCID);
> + else
> + tst_resm(TFAIL, "%s(PARENT) failed.", TCID);
> + return 0;
> +}
> +
> +/* Setup specific to child process */
> +int do_child_setup(void *file)
> +{
> + int pid, ret, sd;
> + int bytes;
> + char *newfile;
> + char command[80];
> + pid = getpid();
> +
> + /* Activate loopback interface */
> + if (system("ifconfig lo up") != 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: activating loopback failed\n", pid);
> + tst_resm(TINFO, "%d: activated loopback.", pid);
> +
> + /* Activate echo service */
> + if (system("xinetd -pidfile /tmp/echoc01-xinetd-c.pid \
> + -stayalive -inetd_compat") != 0) {
> + tst_resm(TBROK, "%d: activating xinetd failed\n", pid);
> + return 1;
> + }
> + tst_resm(TINFO, "%d: activated xinetd services.", pid);
> +
> + /* Wake up parent waiting for this point (stage 1) */
> + system("cat /tmp/FIFO-sync > /dev/null");
> +
> + /* Create a socket and connect it to echo service */
> + sd = do_connect_socket();
> + tst_resm(TINFO, "%d: child has connected socket.", pid);
> +
> + /* Wake up parent waiting for this point (stage 2) */
> + system("echo sync stage 2 > /tmp/FIFO-sync");
> +
> + /* Write data in socket connected to echo service */
> + bytes = do_echofile(sd, file);
> + tst_resm(TINFO, "%d: child has written into echo port.", pid);
> +
> + /* Wake up parent waiting for this point (stage 3) */
> + system("cat /tmp/FIFO-sync > /dev/null");
> +
> + /* Read data that is being echoed */
> + newfile = malloc(strlen(file) + 1);
> + newfile = memcpy(newfile, file, strlen(file)+1);
> + newfile = strcat(newfile, ".echo");
> + ret = do_read_from_echo(sd, bytes, newfile);
> + tst_resm(TINFO, "%d: child has readback from echo.", pid);
> +
> + /* Close sockets and perform cleanup */
> + do_close_socket(sd);
> + do_cleanup();
> +
> + /* Validate the data that is echoed */
> + sprintf(command, "cmp -s %s %s", (char *)file, newfile);
> + if (system(command) == 0)
> + tst_resm(TPASS, "%s(CHILD) passed.", TCID);
> + else
> + tst_resm(TFAIL, "%s(CHILD) failed.", TCID);
> + return 0;
> +}
> +
> +int do_connect_socket()
> +{
> + struct hostent *hent_ptr;
> + struct servent *sent_ptr;
> + struct protoent *pent_ptr;
> + struct sockaddr_in sa_in;
> + struct sockaddr_in sa;
> + socklen_t sa_size;
> + struct in_addr hostaddr;
> + int sd, port;
> + int pid;
> + pid = getpid();
> +
> + pent_ptr = getprotobyname("IP");
> +
> + sd = socket(PF_INET, SOCK_STREAM, pent_ptr->p_proto);
> + if (sd < 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: socket() failed with error: %s\n",\
> + pid, strerror(errno));
> +
> + hent_ptr = gethostbyname("localhost");
> + if (hent_ptr == NULL)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: gethostbyname() failed with error: %s\n",\
> + pid, hstrerror(h_errno));
> +
> + sent_ptr = getservbyname("echo", "tcp");
> + if (sent_ptr == NULL)
> + tst_brkm(TWARN, do_cleanup,\
> + "%d: getservbyname() failed to get service entry\n",
> + pid);
> +
> + port = sent_ptr->s_port;
> + memcpy(&hostaddr, hent_ptr->h_addr_list[0], sizeof(struct in_addr));
> + memset((char *)&sa_in, 0x00, sizeof(sa_in));
> + sa_in.sin_port = port;
> + sa_in.sin_family = PF_INET;
> + sa_in.sin_addr = hostaddr;
> + tst_resm(TINFO, "%d: host name is %s", pid, hent_ptr->h_name);
> +
> + if (connect(sd, (struct sockaddr *) &sa_in, sizeof(sa_in)) < 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: connect() failed with error: %s\n",\
> + pid, strerror(errno));
> +
> + sa_size = sizeof(sa);
> + if (getsockname(sd, (struct sockaddr *) &sa, &sa_size) != 0)
> + tst_brkm(TWARN, do_cleanup,\
> + "%d: getsockname() failed with error : %s",\
> + pid, strerror(errno));
> +
> + tst_resm(TINFO, "%d: local port is %d", pid, ntohs(sa.sin_port));
> +
> + if (getpeername(sd, (struct sockaddr *) &sa, &sa_size) != 0)
> + tst_brkm(TWARN, do_cleanup,\
> + "%d: getpeername() failed with error : %s",\
> + pid, strerror(errno));
> +
> + tst_resm(TINFO, "%d: remote port is %d", pid, ntohs(sa.sin_port));
> +
> + return sd;
> +}
> +
> +int do_echofile(int sd, char *file)
> +{
> + char buffer[BUFFER_SIZE];
> + int read_flag = 1, fdr, pid;
> + int bytes = 0;
> + unsigned int nbytes_r = 0, nbytes_w = 0;
> + unsigned long bufindex;
> +
> + pid = getpid();
> + fdr = open(file, O_RDONLY);
> + if (fdr < 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: failed to open %s: %s",\
> + pid, file, strerror(errno));
> +
> + while (read_flag) {
> + /* Flushout the buffer and initialize counters */
> + memset((char *)&buffer, 0x00, sizeof(buffer));
> +
> + if (nbytes_r == 0) {
> + bufindex = 0;
> + /* Read till the end of file */
> + nbytes_r = read(fdr, buffer, sizeof(buffer));
> + if (nbytes_r < 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: failed to read from %s: %s",\
> + pid, file, strerror(errno));
> + }
> +
> + if (nbytes_r == 0) {
> + /* Reached end of file */
> + break;
> + }
> +
> + /* Write into socket whatever is read now */
> + nbytes_w = write(sd, buffer + bufindex, nbytes_r);
> + if (nbytes_w < 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: failed to write in socket: %s",\
> + pid, strerror(errno));
> +
> + if (nbytes_w < nbytes_r) {
> + /* Write is not complete */
> + nbytes_r -= nbytes_w;
> + bufindex += nbytes_w;
> + }
> +
> + if (nbytes_w == nbytes_r)
> + nbytes_r = 0;
> +
> + bytes += nbytes_w;
> + nbytes_w = 0;
> + }
> +
> + if (close(fdr) < 0)
> + tst_resm(TWARN,\
> + "%d: closing %s failed: %s",\
> + pid, file, strerror(errno));
> + return bytes;
> +}
> +
> +int do_read_from_echo(int sd, int bytes_tot, char *file)
> +{
> + char buffer[BUFFER_SIZE];
> + int pid, fdw, read_flag = 1;
> + int nbytes_w = 0, nbytes_r = 0;
> + int bytes_read = 0;
> + unsigned long bufindex;
> +
> + pid = getpid();
> + fdw = creat(file, S_IRWXU|S_IRWXG|S_IROTH);
> + if (fdw < 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: failed to create %s: %s",\
> + pid, file, strerror(errno));
> +
> + while (read_flag) {
> + /* Flushout the buffer and initialize counters */
> + memset((char *)&buffer, 0x00, sizeof(buffer));
> + if (nbytes_w == nbytes_r) {
> + nbytes_w = 0;
> + nbytes_r = 0;
> + bufindex = 0;
> + }
> +
> + if (nbytes_r == 0) {
> + nbytes_r = read(sd, buffer, sizeof(buffer));
> + if (nbytes_r < 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: failed to read from socket: %s",\
> + pid, strerror(errno));
> + }
> +
> + bytes_read += nbytes_r;
> +
> + /* Write into newfile whatever is just read from socket */
> + nbytes_w = write(fdw, buffer + bufindex , nbytes_r);
> + if (nbytes_w < 0)
> + tst_brkm(TBROK, do_cleanup,\
> + "%d: failed to write into file %s: %s",\
> + pid, file, strerror(errno));
> +
> + if (nbytes_w < nbytes_r) {
> + /* Write is not complete */
> + nbytes_r -= nbytes_w;
> + bufindex += nbytes_w;
> + }
> +
> + if (bytes_read == bytes_tot) {
> + /* Reached end of file */
> + break;
> + }
> + }
> +
> + if (close(fdw) < 0)
> + tst_brkm(TWARN, do_cleanup,\
> + "%d: closing %s failed: %s",\
> + pid, file, strerror(errno));
> + return 0;
> +}
> +
> +void do_close_socket(int sd)
> +{
> + int pid;
> + pid = getpid();
> + if (close(sd) < 0)
> + tst_resm(TWARN,\
> + "%d: closing socket failed: %s",\
> + pid, strerror(errno));
> +}
> +
> +int main(int argc, char **argv)
> +{
> + int ret;
> + int flags;
> + do_setup();
> + flags = CLONE_NEWNET;
> + flags |= CLONE_NEWNS;
> + ret = do_unshare_tests(flags,
> + do_child_setup, "echoc01-child.dat",
> + do_parent_setup, "echoc01-parent.dat");
> + exit(ret);
> +}
> +
>
> --
> Gowrishankar
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list