From: Nathan Scott Date: Wed, 17 Jan 2001 01:24:14 +0000 (+0000) Subject: cmd/xfsprogs/libdm/dmapi_tests/README 1.1 Renamed to cmd/xfstests/dmapi/README X-Git-Tag: v1.1.0~1334 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=785bb637318fd90cfb6bce4890d8edb99667c3f6;p=users%2Fhch%2Fxfstests-dev.git cmd/xfsprogs/libdm/dmapi_tests/README 1.1 Renamed to cmd/xfstests/dmapi/README --- diff --git a/dmapi/README b/dmapi/README new file mode 100644 index 000000000..af7706016 --- /dev/null +++ b/dmapi/README @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + + +The tests in this directory are a collection of suites that were developed +over the time the DMAPI spec was being created and when DMAPI was being +implemented on Irix. In many cases, each suite was built on an earlier suite. +Many of these tests have been ported to work with XFS/DMAPI on linux 2.4; many +are untouched from their Irix versions. diff --git a/dmapi/src/common/cmd/read_invis.c b/dmapi/src/common/cmd/read_invis.c new file mode 100644 index 000000000..ea01855ac --- /dev/null +++ b/dmapi/src/common/cmd/read_invis.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#include + +#ifdef linux +#include +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_read_invis(). The +command line is: + + read_invis [-o offset] [-l length] [-s sid] pathname + +where: +'offset' is the offset of the start of the write (0 is the default), +'length' is the length of the write in bytes (1 is the default), +'sid' is the session ID whose events you you are interested in. +'pathname' is the name of the file to be written. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-o offset] [-l length] " + "[-s sid] pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname = NULL; + dm_off_t offset = 0; + dm_size_t length = 1; + char *bufp = NULL; + void *hanp; + size_t hlen; + dm_ssize_t rc; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "o:l:s:")) != EOF) { + switch (opt) { + case 'o': + offset = atol(optarg); + break; + case 'l': + length = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", pathname); + exit(1); + } + + if (length > 0) { + /* In case it is a realtime file, align the buffer on a + sufficiently big boundary. + */ + if ((bufp = memalign(4096, length)) == NULL) { + fprintf(stderr, "malloc of %d bytes failed\n", length); + exit(1); + } + memset(bufp, '\0', length); + } + + rc = dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN, offset, length, bufp); + + if (rc < 0) { + fprintf(stderr, "dm_read_invis failed, %s\n", strerror(errno)); + exit(1); + } else if (rc != length) { + fprintf(stderr, "expected to read %lld bytes, actually " + "read %lld\n", length, rc); + exit(1); + } + for (i = 0; i < rc; i++) { + if (isprint(bufp[i])) { + fprintf(stdout, "%c", bufp[i]); + } else { + fprintf(stdout, "\\%03d", bufp[i]); + } + } + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/common/cmd/set_region.c b/dmapi/src/common/cmd/set_region.c new file mode 100644 index 000000000..c4ed4ae84 --- /dev/null +++ b/dmapi/src/common/cmd/set_region.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_set_region(). The +command line is: + + set_region [-n nelem] [-o offset] [-l length] [-s sid] pathname [event...] + +where pathname is the name of a file, nelem is the number of regions to pass +in the call, offset is the offset of the start of +the managed region, and length is the length. sid is the session ID whose +events you you are interested in, and event is zero or more managed region +events to set. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static struct { + char *name; + int value; +} rg_events[3] = { + { "DM_REGION_READ", DM_REGION_READ }, + { "DM_REGION_WRITE", DM_REGION_WRITE }, + { "DM_REGION_TRUNCATE", DM_REGION_TRUNCATE } +}; +static int nevents = sizeof(rg_events)/sizeof(rg_events[0]); + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-n nelem] [-o offset] [-l length] " + "[-s sid] pathname [event...]\n", Progname); + fprintf(stderr, "possible events are:\n"); + for (i = 0; i < nevents; i++) + fprintf(stderr, "%s (0x%x)\n", rg_events[i].name, rg_events[i].value); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_region_t region = { 0, 0, 0 }; + dm_sessid_t sid = DM_NO_SESSION; + char *pathname = NULL; + u_int exactflag; + u_int nelem = 1; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "n:o:l:s:")) != EOF) { + switch (opt) { + case 'n': + nelem = atol(optarg); + break; + case 'o': + region.rg_offset = atol(optarg); + break; + case 'l': + region.rg_size = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 > argc) + usage(); + pathname = argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", pathname); + exit(1); + } + + for (; optind < argc; optind++) { + if (strspn(argv[optind], "0123456789") == strlen(argv[optind])){ + region.rg_flags |= atol(argv[optind]); + continue; + } + for (i = 0; i < nevents; i++) { + if (!strcmp(argv[optind], rg_events[i].name)) + break; + } + if (i == nevents) { + fprintf(stderr, "invalid event %s\n", argv[optind]); + exit(1); + } + region.rg_flags |= rg_events[i].value; + } + + if (dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelem, ®ion, + &exactflag)) { + fprintf(stderr, "dm_set_region failed, %s\n", + strerror(errno)); + exit(1); + } + fprintf(stdout, "exactflag is %s\n", + exactflag == DM_TRUE ? "True" : "False"); + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/common/cmd/set_return_on_destroy.c b/dmapi/src/common/cmd/set_return_on_destroy.c new file mode 100644 index 000000000..b670d9b8f --- /dev/null +++ b/dmapi/src/common/cmd/set_return_on_destroy.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_set_return_on_destroy(). The +command line is: + + set_return_on_destroy [-s sid] pathname [attr] + +where pathname is the name of a file which resides in the filesystem of +interest. attr is the name of the DMAPI attribute; if none is specified, +then set-return-on-destroy will be disabled for the filesystem. +sid is the session ID whose attribute you are interested in setting. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-s sid] pathname [attr]\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname; + dm_attrname_t *attrnamep = NULL; + dm_boolean_t enable = DM_FALSE; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "s:")) != EOF) { + switch (opt) { + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind == argc || optind + 2 < argc) + usage(); + pathname = argv[optind++]; + if (optind < argc) { + enable = DM_TRUE; + attrnamep = (dm_attrname_t *)argv[optind++]; + } + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_fshandle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get filesystem handle for file %s, %s\n", + pathname, strerror(errno)); + exit(1); + } + + if (dm_set_return_on_destroy(sid, hanp, hlen, DM_NO_TOKEN, + attrnamep, enable)) { + fprintf(stderr, "dm_set_return_on_destroy failed, %s\n", + strerror(errno)); + exit(1); + } + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/common/cmd/write_invis.c b/dmapi/src/common/cmd/write_invis.c new file mode 100644 index 000000000..0dcbd3090 --- /dev/null +++ b/dmapi/src/common/cmd/write_invis.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_write_invis(). The +command line is: + + write_invis [-c char] [-o offset] [-l length] [-s sid] pathname + +where: +'char' is the character to use as a repeated pattern ('X' is the default), +'offset' is the offset of the start of the write (0 is the default), +'length' is the length of the write in bytes (1 is the default), +'sid' is the session ID whose events you you are interested in. +'pathname' is the name of the file to be written. + +DM_WRITE_SYNC is is not supported. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-c char] [-o offset] [-l length] " + "[-s sid] pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname = NULL; + dm_off_t offset = 0; + dm_size_t length = 1; + u_char ch = 'X'; + void *bufp = NULL; + void *hanp; + size_t hlen; + dm_ssize_t rc; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "c:o:l:s:")) != EOF) { + switch (opt) { + case 'c': + ch = *optarg; + break; + case 'o': + offset = atol(optarg); + break; + case 'l': + length = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", pathname); + exit(1); + } + + if (length > 0) { + /* In case it is a realtime file, align the buffer on a + sufficiently big boundary. + */ + if ((bufp = memalign(4096, length)) == NULL) { + fprintf(stderr, "malloc of %d bytes failed\n", length); + exit(1); + } + memset(bufp, ch, length); + } + + rc = dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0, offset, length, bufp); + + if (rc < 0) { + fprintf(stderr, "dm_write_invis failed, %s\n", strerror(errno)); + exit(1); + } else if (rc != length) { + fprintf(stderr, "expected to write %lld bytes, actually " + "wrote %lld\n", length, rc); + exit(1); + } + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/common/lib/dmport.h b/dmapi/src/common/lib/dmport.h new file mode 100644 index 000000000..b7722f6a5 --- /dev/null +++ b/dmapi/src/common/lib/dmport.h @@ -0,0 +1,901 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#ifndef _DMFSAPI_DMPORT_H +#define _DMFSAPI_DMPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************** + * * + * DMF's use of DMAPI is based upon the X/Open document * + * Systems Management: Data Storage Managment (XDSM) API * + * dated February 1997. However, no implementation of DMAPI perfectly * + * matches the spec. Each implementation has some functions that it * + * didn't implement, non-standard functions that it added, differences * + * in function parameter types, return value types, number and order of * + * parameters, etc. There are also differences in the formats of some * + * of the DMAPI structures used by those functions. Finally, there are * + * many scalar values for which DMAPI assigned no particular size. For * + * example, a dm_fsid_t is 32 bits under Veritas and 64 bits under SGI. * + * * + * To hide the differences as much as possible, this include file tries * + * to shoehorn each DMAPI implementation into the XDSM mold as much as * + * possible. Functions which are not compatible with the XDSM spec are * + * redefined using wrapper routines to make them conform to the spec. * + * Functions which were not implemented have stubs defined which return * + * ENOSYS (see file stubs.c for all wrappers and stubs). In dmport.h, * + * missing structures and scalers are defined, incompatible typedefs are * + * redefined, etc. * + * * + * The goal is to reduce as much as possible the number of #ifdefs that * + * have to be added to DMF to handle specific DMAPI implementations. * + * Some #ifdefs may still be required because of semantic differences * + * between the XDSM spec definition and the actual implementation. * + * * + * Following all the implementation-specific definitions, dmport.h * + * includes a complete set of prototypes for all functions that are part * + * of the XDSM specification. This is done as a double-check. Should * + * any of the actual implementations change, the compiler should tip us * + * off by complaining about imcompatible function redefinitions. * + * * + **************************************************************************/ + + +/* ---------------- Veritas-specific hack documentation ----------------- + +The following functions have no prototypes in the Veritas include file +. They do not link either. + +extern int dm_handle_is_valid(void *, size_t); + + +The following functions have prototypes in , but +they do not link. + +extern int dm_getall_disp(dm_sessid_t, size_t, void *, size_t *); +extern int dm_getall_dmattr(dm_sessid_t, void *, size_t, + dm_token_t, size_t, void *, size_t *); + + +The following functions have no prototypes in but do link. + +extern int dm_obj_ref_hold(dm_sessid_t, dm_token_t, void *, size_t); +extern int dm_obj_ref_rele(dm_sessid_t, dm_token_t, void *, size_t); +extern int dm_obj_ref_query(dm_sessid_t, dm_token_t, void *, size_t); + + +The following Veritas prototypes are different in some way from the +spec prototypes, either in parameter types, return value types, or in +some semantic way. Look below to see the spec versions of the prototypes. + +extern int dm_downgrade_right(dm_sessid_t, void *, size_t, + dm_token_t, int, dm_right_t); +extern int dm_get_config_events(void *, size_t, u_int, + dm_eventset_t *, u_int *); +extern int dm_get_events(dm_sessid_t, u_int, int, size_t, void *, size_t *); +extern int dm_get_mountinfo(dm_sessid_t, dm_token_t, void *, size_t, + size_t, void *, size_t *); +extern int dm_init_service(void); +extern int dm_make_handle(dev_t , long, long, void **, size_t *); +extern int dm_make_fshandle(dev_t , void **, size_t *); +extern dev_t dm_handle_to_dev(void *, size_t); +extern long dm_handle_to_fgen(void *, size_t); +extern long dm_handle_to_ino(void *, size_t); +extern int dm_pending(dm_sessid_t, void *, size_t, dm_token_t, int); +extern dm_ssize_t dm_read_invis(dm_sessid_t, void *, size_t, + dm_token_t, dm_off_t, dm_ssize_t, void *); +extern dm_ssize_t dm_write_invis(dm_sessid_t, void *, size_t, + dm_token_t, dm_off_t, dm_ssize_t, void *, int); +extern int dm_request_right(dm_sessid_t, void *, size_t, + dm_token_t, int, dm_right_t); +extern int dm_set_inherit(dm_sessid_t, void *, size_t, + dm_token_t, dm_attrname_t *, u_int); +extern int dm_set_return_ondestroy(dm_sessid_t, void *, size_t, + dm_token_t, dm_attrname_t *, int); +extern int dm_upgrade_right(dm_sessid_t, void *, size_t, + dm_token_t, int, dm_right_t); +extern int dm_set_region(dm_sessid_t, void *, size_t, + dm_token_t, u_int, dm_region_t *, u_int *); +extern dm_ssize_t dm_sync_by_handle(dm_sessid_t, void *, size_t, dm_token_t); + + +The following Veritas prototype exists in but +does not appear in the spec. + +extern void dm_attach_event(dm_sessid_t, dm_token_t); + +The following functions exist in the Veritas library libdmi.a, but have no +prototypes within . Their function is unknown. + +dm_attach_event_nofork +dm_event_query +dm_event_valid +dm_get_disp +dm_set_resident +dmregion_compare +kdm_get_eventinfo +kdm_get_sessioninfo + +-------------- end of Veritas-specific hack documentation --------------- */ + +#ifdef VERITAS_21 + +#include + +#include + +/* Rename functions whose prototypes clash with the XDSM standard. (Library + routines map from XDSM functions back to Veritas functions.) +*/ + +#define dm_downgrade_right xvfs_dm_downgrade_right +#define dm_fd_to_handle xvfs_dm_fd_to_handle +#define dm_get_events xvfs_dm_get_events +#define dm_get_mountinfo xvfs_dm_get_mountinfo +#define dm_handle_to_ino xvfs_dm_handle_to_ino +#define dm_init_service xvfs_dm_init_service +#define dm_make_fshandle xvfs_dm_make_fshandle +#define dm_make_handle xvfs_dm_make_handle +#define dm_path_to_fshandle xvfs_dm_path_to_fshandle +#define dm_path_to_handle xvfs_dm_path_to_handle +#define dm_pending xvfs_dm_pending +#define dm_read_invis xvfs_dm_read_invis +#define dm_write_invis xvfs_dm_write_invis +#define dm_request_right xvfs_dm_request_right +#define dm_set_inherit xvfs_dm_set_inherit +#define dm_set_region xvfs_dm_set_region +#define dm_sync_by_handle xvfs_dm_sync_by_handle +#define dm_upgrade_right xvfs_dm_upgrade_right + + +#define DM_ATTR_NAME_SIZE 8 +#undef DM_ATTRNAME_SIZE +#define DM_VER_STR_CONTENTS "Veritas DMAPI V1.0" + +#define DM_EV_WAIT 0x1 +#define DM_RR_WAIT 0x1 +#undef DM_WAIT +#undef DM_NOWAIT +#undef DM_EVENT_NOWAIT + +#define DM_CONFIG_INHERIT_ATTRIBS (DM_CONFIG_LOCK_UPGRADE + 1) +#undef DM_CONFIG_INHERIT +#define DM_CONFIG_MAX_HANDLE_SIZE (DM_CONFIG_INHERIT_ATTRIBS + 1) +#undef DM_CONFIG_MAX_FILE_HANDLE_SIZE +#define DM_CONFIG_MAX_ATTR_ON_DESTROY (DM_CONFIG_MAX_HANDLE_SIZE + 1) +#undef DM_CONFIG_MAX_ATTR_BYTES_ON_DESTROY +#define DM_CONFIG_OBJ_REF (DM_CONFIG_MAX_ATTR_ON_DESTROY + 1) +#define DM_CONFIG_DTIME_OVERLOAD (DM_CONFIG_OBJ_REF + 1) +#undef DM_CONFIG_MAX + +#define DM_AT_DTIME DM_AT_DTIMES + +/* In the dm_fileattr_t structure, Veritas used 'timeval' structures for all + the time fields while XDSM uses 'time_t' structures. Define some symbols + that can be used for the time fields with all implementation types. +*/ + +#define FA_ATIME fa_atime.tv_sec +#define FA_MTIME fa_atime.tv_sec +#define FA_CTIME fa_ctime.tv_sec +#define FA_DTIME fa_dtime.tv_sec + +#define DM_WRITE_SYNC 0x1 /* used in dm_write_invis() */ + +#define DM_UNMOUNT_FORCE 0x1 /* ne_mode field in dm_namesp_event_t */ + +/* Rename one event to match the XDSM standard. */ + +#define DM_EVENT_CLOSE (DM_EVENT_DESTROY + 1) +#undef DM_EVENT_CLOSED + +/* DM_EVENT_CANCEL is defined above DM_EVENT_MAX, and is unsupported. */ + +#undef DM_REGION_VALIDFLAG + +/* Add missing typedefs */ + +typedef u_int dm_boolean_t; +typedef dev_t dm_fsid_t; /* This could be made a uint64_t with work! */ +typedef long dm_igen_t; +typedef long dm_ino_t; +typedef u_int dm_sequence_t; + + +/* Define missing fields within the various event structures. */ + +#define ev_sequence ev_token /* for compilation only! Won't work! */ + +#define ds_handle te_handle /* fix fields in dm_destroy_event_t */ +#define ds_attrname te_attrname +#define ds_attrcopy te_attrdata + + +struct dm_cancel_event { /* define missing dm_cancel_event_t */ + dm_sequence_t ce_sequence; + dm_token_t ce_token; +}; +typedef struct dm_cancel_event dm_cancel_event_t; + + +struct dm_mount_event { /* define missing dm_mount_event_t */ + mode_t me_mode; + dm_vardata_t me_handle1; + dm_vardata_t me_handle2; + dm_vardata_t me_name1; + dm_vardata_t me_name2; + dm_vardata_t me_roothandle; +}; +typedef struct dm_mount_event dm_mount_event_t; + + +/* Add the missing dm_timestruct_t structure used by dm_pending. */ + +struct dm_timestruct { + time_t dm_tv_sec; + int dm_tv_nsec; +}; +typedef struct dm_timestruct dm_timestruct_t; + +#endif + + + +/* -------------------- SGI-specific hack documentation ------------------- + + There are various fields within DMAPI structures that are not supported. + Fill in this information someday. + + The following functions have prototypes defined in and have + entry points defined in libdm.so, but they are not actually implemented + within the kernel. They all return ENOSYS if called. + + dm_clear_inherit + dm_create_by_handle + dm_get_bulkall + dm_getall_inherit + dm_mkdir_by_handle + dm_set_inherit + dm_symlink_by_handle + + The DMAPI functions which deal with rights do not work as described in + the specification. While the functions exist and are callable, they + always return successfully without actually obtaining any locks within + the filesystem. + + dm_downgrade_right + dm_query_right + dm_release_right + dm_request_right + dm_upgrade_right + + The following non-standard SGI prototype is added to the DMAPI interface + so that real-time files may be migrated and recalled. + + dm_get_dioinfo + +-------------- end of SGI-specific hack documentation --------------- */ + +#ifdef __sgi + +#include + +/* In the dm_fileattr_t structure, Veritas used 'timeval' structures for all + the time fields while XDSM uses 'time_t' structures. Define some symbols + that can be used for the time fields with all implementation types. +*/ + +#define FA_ATIME fa_atime +#define FA_MTIME fa_mtime +#define FA_CTIME fa_ctime +#define FA_DTIME fa_dtime + +#endif /* __sgi */ + +#ifdef linux + +#include + +/* In the dm_fileattr_t structure, Veritas used 'timeval' structures for all + the time fields while XDSM uses 'time_t' structures. Define some symbols + that can be used for the time fields with all implementation types. +*/ + +#define FA_ATIME fa_atime +#define FA_MTIME fa_mtime +#define FA_CTIME fa_ctime +#define FA_DTIME fa_dtime + +#endif /* linux */ + +/* ----------------------- XDSM standard prototypes ----------------------- */ + +/* The following list provides the prototypes for all functions defined in + the DMAPI interface spec from X/Open (XDSM) dated February 1997. They + are here to force compiler errors in case the Veritas or SGI DMAPI + prototypes should ever change without our knowing about it. +*/ + +extern int +dm_clear_inherit( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_attrname_t *attrnamep); + +extern int +dm_create_by_handle( + dm_sessid_t sid, + void *dirhanp, + size_t dirhlen, + dm_token_t token, + void *hanp, + size_t hlen, + char *cname); + +extern int +dm_create_session( + dm_sessid_t oldsid, + char *sessinfop, + dm_sessid_t *newsidp); + +extern int +dm_create_userevent( + dm_sessid_t sid, + size_t msglen, + void *msgdatap, + dm_token_t *tokenp); + +extern int +dm_destroy_session( + dm_sessid_t sid); + +extern int +dm_downgrade_right( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token); + +extern int +dm_fd_to_handle( + int fd, + void **hanpp, + size_t *hlenp); + +extern int +dm_find_eventmsg( + dm_sessid_t sid, + dm_token_t token, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern int +dm_get_allocinfo( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_off_t *offp, + u_int nelem, + dm_extent_t *extentp, + u_int *nelemp); + +extern int +dm_get_bulkall( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int mask, + dm_attrname_t *attrnamep, + dm_attrloc_t *locp, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern int +dm_get_bulkattr( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int mask, + dm_attrloc_t *locp, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern int +dm_get_config( + void *hanp, + size_t hlen, + dm_config_t flagname, + dm_size_t *retvalp); + +extern int +dm_get_config_events( + void *hanp, + size_t hlen, + u_int nelem, + dm_eventset_t *eventsetp, + u_int *nelemp); + +extern int +dm_get_dirattrs( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int mask, + dm_attrloc_t *locp, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern int +dm_get_dmattr( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_attrname_t *attrnamep, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern int +dm_get_eventlist( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int nelem, + dm_eventset_t *eventsetp, + u_int *nelemp); + +extern int +dm_get_events( + dm_sessid_t sid, + u_int maxmsgs, + u_int flags, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern int +dm_get_fileattr( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int mask, + dm_stat_t *statp); + +extern int +dm_get_mountinfo( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern int +dm_get_region( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int nelem, + dm_region_t *regbufp, + u_int *nelemp); + +extern int +dm_getall_disp( + dm_sessid_t sid, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern int +dm_getall_dmattr( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern int +dm_getall_inherit( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int nelem, + dm_inherit_t *inheritbufp, + u_int *nelemp); + +extern int +dm_getall_sessions( + u_int nelem, + dm_sessid_t *sidbufp, + u_int *nelemp); + +extern int +dm_getall_tokens( + dm_sessid_t sid, + u_int nelem, + dm_token_t *tokenbufp, + u_int *nelemp); + +extern int +dm_handle_cmp( + void *hanp1, + size_t hlen1, + void *hanp2, + size_t hlen2); + +extern void +dm_handle_free( + void *hanp, + size_t hlen); + +extern u_int +dm_handle_hash( + void *hanp, + size_t hlen); + +extern dm_boolean_t +dm_handle_is_valid( + void *hanp, + size_t hlen); + +extern int +dm_handle_to_fshandle( + void *hanp, + size_t hlen, + void **fshanpp, + size_t *fshlenp); + +extern int +dm_handle_to_fsid( + void *hanp, + size_t hlen, + dm_fsid_t *fsidp); + +extern int +dm_handle_to_igen( + void *hanp, + size_t hlen, + dm_igen_t *igenp); + +extern int +dm_handle_to_ino( + void *hanp, + size_t hlen, + dm_ino_t *inop); + +extern int +dm_handle_to_path( + void *dirhanp, + size_t dirhlen, + void *targhanp, + size_t targhlen, + size_t buflen, + char *pathbufp, + size_t *rlenp); + +extern int +dm_init_attrloc( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_attrloc_t *locp); + +extern int +dm_init_service( + char **versionstrpp); + +extern int +dm_make_fshandle( + dm_fsid_t *fsidp, + void **hanpp, + size_t *hlenp); + +extern int +dm_make_handle( + dm_fsid_t *fsidp, + dm_ino_t *inop, + dm_igen_t *igenp, + void **hanpp, + size_t *hlenp); + +extern int +dm_mkdir_by_handle( + dm_sessid_t sid, + void *dirhanp, + size_t dirhlen, + dm_token_t token, + void *hanp, + size_t hlen, + char *cname); + +extern int +dm_move_event( + dm_sessid_t srcsid, + dm_token_t token, + dm_sessid_t targetsid, + dm_token_t *rtokenp); + +extern int +dm_obj_ref_hold( + dm_sessid_t sid, + dm_token_t token, + void *hanp, + size_t hlen); + +extern int +dm_obj_ref_query( + dm_sessid_t sid, + dm_token_t token, + void *hanp, + size_t hlen); + +extern int +dm_obj_ref_rele( + dm_sessid_t sid, + dm_token_t token, + void *hanp, + size_t hlen); + +extern int +dm_path_to_fshandle( + char *path, + void **hanpp, + size_t *hlenp); + +extern int +dm_path_to_handle( + char *path, + void **hanpp, + size_t *hlenp); + +extern int +dm_pending( + dm_sessid_t sid, + dm_token_t token, + dm_timestruct_t *delay); + +extern int +dm_probe_hole( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_off_t off, + dm_size_t len, + dm_off_t *roffp, + dm_size_t *rlenp); + +extern int +dm_punch_hole( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_off_t off, + dm_size_t len); + +extern int +dm_query_right( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_right_t *rightp); + +extern int +dm_query_session( + dm_sessid_t sid, + size_t buflen, + void *bufp, + size_t *rlenp); + +extern dm_ssize_t +dm_read_invis( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_off_t off, + dm_size_t len, + void *bufp); + +extern int +dm_release_right( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token); + +extern int +dm_remove_dmattr( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + int setdtime, + dm_attrname_t *attrnamep); + +extern int +dm_request_right( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int flags, + dm_right_t right); + +extern int +dm_respond_event( + dm_sessid_t sid, + dm_token_t token, + dm_response_t response, + int reterror, + size_t buflen, + void *respbufp); + +extern int +dm_send_msg( + dm_sessid_t targetsid, + dm_msgtype_t msgtype, + size_t buflen, + void *bufp); + +extern int +dm_set_disp( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_eventset_t *eventsetp, + u_int maxevent); + +extern int +dm_set_dmattr( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_attrname_t *attrnamep, + int setdtime, + size_t buflen, + void *bufp); + +extern int +dm_set_eventlist( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_eventset_t *eventsetp, + u_int maxevent); + +extern int +dm_set_fileattr( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int mask, + dm_fileattr_t *attrp); + +extern int +dm_set_inherit( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_attrname_t *attrnamep, + mode_t mode); + +extern int +dm_set_region( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int nelem, + dm_region_t *regbufp, + dm_boolean_t *exactflagp); + +extern int +dm_set_return_on_destroy( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_attrname_t *attrnamep, + dm_boolean_t enable); + +extern int +dm_symlink_by_handle( + dm_sessid_t sid, + void *dirhanp, + size_t dirhlen, + dm_token_t token, + void *hanp, + size_t hlen, + char *cname, + char *path); + +extern int +dm_sync_by_handle( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token); + +extern int +dm_upgrade_right( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token); + +extern dm_ssize_t +dm_write_invis( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + int flags, + dm_off_t off, + dm_size_t len, + void *bufp); + + +#ifdef __cplusplus +} +#endif + +#endif /* _DMFSAPI_DMPORT_H */ diff --git a/dmapi/src/common/lib/find_session.c b/dmapi/src/common/lib/find_session.c new file mode 100644 index 000000000..2e3d6e1e4 --- /dev/null +++ b/dmapi/src/common/lib/find_session.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + + +/******************************************************************************* +* +* NAME +* find_test_session - find or create a test DMAPI session. +* +* DESCRIPTION +* find_test_session() is used to find a test DMAPI session to +* use. There is only one test session per host; all test processes +* share the same session. If the session does not already exist, +* then the first process to call find_test_session() causes +* the session to be created. +* +* Note: It is possible for N different programs to call this routine +* at the same time. Each would find that a test session does not +* exist, and each one would then create a new test session. Since +* excess test sessions are not automatically released on death of +* process, we need to make sure that we don't leave such excess +* sessions around. So, after creating a session we go back and find +* the test session with the lowest session number. If it is ours, +* great; we are done. If not, then we must destroy our session +* and use the one with the lower session ID. There is still a risk +* here of creating a session and crashing before it can be removed +* again. To deal with this, the daemon will periodically remove all +* test sessions except for the one with the lowest ID value. +* +* RETURN VALUE +* None. +* +*******************************************************************************/ + +#define TEST_MSG "DMAPI test session" + +static int +session_compare( +const void *a, +const void *b) +{ + return(*((dm_sessid_t *)a) - *((dm_sessid_t *)b)); +} + +extern void +find_test_session( + dm_sessid_t *session) +{ + char buffer[DM_SESSION_INFO_LEN]; + dm_sessid_t *sidbuf = NULL; + dm_sessid_t new_session; + u_int allocelem = 0; + u_int nelem; + size_t rlen; + int error; + int rc; + u_int i; + + /* Retrieve the list of all active sessions on the host. */ + + nelem = 100; /* a reasonable first guess */ + do { + if (allocelem < nelem) { + allocelem = nelem; + sidbuf = realloc(sidbuf, nelem * sizeof(*sidbuf)); + if (sidbuf == NULL) { + fprintf(stderr, "realloc of %d bytes failed\n", + nelem * sizeof(*sidbuf)); + exit(1); + } + } + error = dm_getall_sessions(allocelem, sidbuf, &nelem); + } while (error < 0 && errno == E2BIG); + + /* If an error occurred, translate it into something meaningful. */ + + if (error < 0) { + fprintf(stderr, "unexpected dm_getall_sessions failure, %s\n", + strerror(errno)); + free(sidbuf); + exit(1); + } + + /* We have the list of all active sessions. Scan the list looking + for an existing "test" session that we can use. The list must + first be sorted in case other processes happen to be creating test + sessions at the same time; we need to make sure that we pick the one + with the lowest session ID. + */ + + qsort(sidbuf, nelem, sizeof(sidbuf[0]), session_compare); + + for (i = 0; i < nelem; i++) { + error = dm_query_session(sidbuf[i], sizeof(buffer), + buffer, &rlen); + if (error < 0) { + fprintf(stderr, "unexpected dm_query_session " + "failure, %s\n", strerror(errno)); + free(sidbuf); + exit(1); + } + + if (!strncmp(buffer, TEST_MSG, strlen(TEST_MSG))) + break; + } + if (i < nelem) { + *session = (dm_sessid_t)sidbuf[i]; + free(sidbuf); + return; + } + + /* No test session exists, so we have to create one ourselves. */ + + if (dm_create_session(DM_NO_SESSION, TEST_MSG, &new_session) != 0) { + fprintf(stderr, "dm_create_session failed, %s\n", + strerror(errno)); + free(sidbuf); + exit(1); + } + + /* Now re-retrieve the list of active sessions. */ + + do { + if (allocelem < nelem) { + allocelem = nelem; + sidbuf = realloc(sidbuf, nelem * sizeof(*sidbuf)); + if (sidbuf == NULL) { + fprintf(stderr, "realloc of %d bytes failed\n", + nelem * sizeof(*sidbuf)); + exit(1); + } + } + error = dm_getall_sessions(allocelem, sidbuf, &nelem); + } while (error < 0 && errno == E2BIG); + + if (error < 0) { + fprintf(stderr, "dm_getall_sessions failed, %s\n", + strerror(errno)); + free(sidbuf); + exit(1); + } + + /* Sort the session ID list into ascending ID order, then find the + test session with the lowest session ID. We better find at + least one since we created one! + */ + + qsort(sidbuf, nelem, sizeof(sidbuf[0]), session_compare); + + for (i = 0; i < nelem; i++) { + error = dm_query_session(sidbuf[i], sizeof(buffer), + buffer, &rlen); + if (error < 0) { + fprintf(stderr, "dm_query_session failed, %s\n", + strerror(errno)); + free(sidbuf); + exit(1); + } + if (!strncmp(buffer, TEST_MSG, strlen(TEST_MSG))) + break; + } + if (i == nelem) { + fprintf(stderr, "can't find the session we created\n"); + free(sidbuf); + exit(1); + } + *session = (dm_sessid_t)sidbuf[i]; + free(sidbuf); + + /* If the session we are going to use is not the one we created, + then we need to get rid of the created one. + */ + + if (*session != new_session) { + if ((new_session) != 0) { + fprintf(stderr, "dm_destroy_session failed, %s\n", + strerror(errno)); + exit(1); + } + } +} diff --git a/dmapi/src/common/lib/hsm.h b/dmapi/src/common/lib/hsm.h new file mode 100644 index 000000000..e09c1f989 --- /dev/null +++ b/dmapi/src/common/lib/hsm.h @@ -0,0 +1,166 @@ +/* + * Defines and structures for our pseudo HSM example + * + * This code was written by Peter Lawthers, and placed in the public + * domain for use by DMAPI implementors and app writers. + * + * Standard disclaimer: + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _LIB_HSM_H +#define _LIB_HSM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include + +#include + +#define HANDLE_LEN 64 /* Swag for this example */ +#define HANDLE_STR ((HANDLE_LEN * 2) + 1) /* handle as ascii, plus null */ +#define IBUFSIZE 1024 /* input buffer size */ +#define CHUNKSIZE (1024*1024*4) /* write size */ +#define FENCEPOST_SIZE ((dm_size_t)(1024*8)) +#define ALL_AVAIL_MSGS 0 + +/* + * Actions to be performed by the worker bees + */ +#define RESTORE_FILE "-r" +#define INVAL_FILE "-i" + +#define WORKER_BEE "wbee" + + +/* + * Names of DM attribute used for storing location of a file's data. + * DM attributes are 8 bytes, including NULL. + */ + +#define DLOC_HAN "dhanloc" /* staging file handle */ +#define DLOC_HANLEN "dhanlen" /* staging handle length */ + +/* + * Default log file + */ +#define LOG_DEFAULT "/tmp/dmig_log" + +struct ev_name_to_value { + char *name; /* name of event */ + dm_eventtype_t value; /* value of event */ +}; + +extern struct ev_name_to_value ev_names[]; +extern int ev_namecnt; + + +struct rt_name_to_value { + char *name; /* name of right */ + dm_right_t value; /* value of right */ +}; + +extern struct rt_name_to_value rt_names[]; +extern int rt_namecnt; + + +extern void hantoa(void *hanp, size_t hlen, char *handle_str); +extern int atohan(char *handle_str, void **hanpp, size_t *hlenp); +extern void print_handle(void *hanp, size_t hlen); +extern void print_victim(void *hanp, size_t hlen, dm_off_t fsize); +extern void errno_msg(char *fmt, ...); +extern void err_msg(char *fmt, ...); +extern int setup_dmapi(dm_sessid_t *sid); +extern int get_dmchange(dm_sessid_t sid, void *hanp, size_t hlen, + dm_token_t token, u_int *change_start); +extern int save_filedata(dm_sessid_t sid, void *hanp, size_t hlen, + int stg_fd, dm_size_t fsize); +extern int restore_filedata(dm_sessid_t sid, void *hanp, size_t hlen, + dm_token_t token, void *stg_hanp, size_t stg_hlen, dm_off_t off); + +extern void find_test_session(dm_sessid_t *session); + +void +print_one_mount_event( + void *msg); + +int +print_one_message( + dm_eventmsg_t *msg); + +int +handle_message( + dm_sessid_t sid, + dm_eventmsg_t *msg); + +extern char *date_to_string( + time_t timeval); + +extern char *mode_to_string( + mode_t mode); + +extern mode_t field_to_mode( + mode_t mode); + +extern int validate_state( + dm_stat_t *dmstat, + char *pathname, + int report_errors); + +extern char *emask_to_string( + dm_eventset_t emask); + +extern char *xflags_to_string( + u_int xflags); + +extern void print_state( + dm_stat_t *dmstat); + +extern void print_line( + dm_stat_t *dmstat); + +extern dm_eventtype_t +ev_name_to_value( + char *name); + +extern char * +ev_value_to_name( + dm_eventtype_t event); + +extern int +rt_name_to_value( + char *name, + dm_right_t *rightp); + +extern char * +rt_value_to_name( + dm_right_t right); + +extern int +opaque_to_handle( + char *name, + void **hanpp, + size_t *hlenp); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIB_HSM_H */ diff --git a/dmapi/src/common/lib/print.c b/dmapi/src/common/lib/print.c new file mode 100644 index 000000000..daec180c9 --- /dev/null +++ b/dmapi/src/common/lib/print.c @@ -0,0 +1,620 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include +#include + +#include + +#include + +#ifdef linux +#define MAXNAMELEN 256 +#endif + + /* + * Define some standard formats for the printf statements below. + */ + +#define HDR "%s: token %d sequence %d\n" +#define VALS "\t%-15s %s\n" +#define VALD "\t%-15s %d\n" +#ifdef __sgi +#define VALLLD "\t%-15s %lld\n" +#else +#define VALLLD "\t%-15s %ld\n" +#endif + + +/* + Convert a mode_t field into a printable string. + + Returns non-zero if the mode_t is invalid. The string is + returned in *ptr, whether there is an error or not. +*/ + +int +format_mode( + mode_t mode, + char **ptr) +{ +static char modestr[100]; + char *typestr; + int error = 0; + + if (S_ISFIFO(mode)) typestr = "FIFO"; + else if(S_ISCHR (mode)) typestr = "Character Device"; + else if(S_ISBLK (mode)) typestr = "Block Device"; + else if(S_ISDIR (mode)) typestr = "Directory"; + else if(S_ISREG (mode)) typestr = "Regular File"; + else if(S_ISLNK (mode)) typestr = "Symbolic Link"; + else if(S_ISSOCK(mode)) typestr = "Socket"; + else { + typestr = ""; + error++; + } + + sprintf(modestr, "mode %06o: perm %c%c%c %c%c%c %c%c%c %c%c%c, type %s", + mode, + mode & S_ISUID ? 's':' ', + mode & S_ISGID ? 'g':' ', + mode & S_ISVTX ? 't':' ', + mode & S_IRUSR ? 'r':'-', + mode & S_IWUSR ? 'w':'-', + mode & S_IXUSR ? 'x':'-', + mode & S_IRGRP ? 'r':'-', + mode & S_IWGRP ? 'w':'-', + mode & S_IXGRP ? 'x':'-', + mode & S_IROTH ? 'r':'-', + mode & S_IWOTH ? 'w':'-', + mode & S_IXOTH ? 'x':'-', + typestr); + *ptr = modestr; + return(error); +} + + +void +print_one_mount_event( + void *msg) +{ + void *hanp1, *hanp2, *hanp3; + size_t hlen1, hlen2, hlen3; + char hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR]; + void *namp1, *namp2; + size_t nlen1, nlen2; + char nams1[MAXNAMELEN], nams2[MAXNAMELEN]; + mode_t mode; + +#if VERITAS_21 + dm_namesp_event_t *msg_ne = (dm_namesp_event_t *)msg; + +/* + msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *); +*/ + hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *); + hlen1 = DM_GET_LEN (msg_ne, ne_handle1); + hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *); + hlen2 = DM_GET_LEN (msg_ne, ne_handle2); + namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *); + nlen1 = DM_GET_LEN (msg_ne, ne_name1); + namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *); + nlen2 = DM_GET_LEN (msg_ne, ne_name2); + hanp3 = NULL; + hlen3 = 0; + mode = msg_ne->ne_mode; +#else + dm_mount_event_t *msg_me = (dm_mount_event_t *)msg; + + hanp1 = DM_GET_VALUE(msg_me, me_handle1, void *); + hlen1 = DM_GET_LEN(msg_me, me_handle1); + hanp2 = DM_GET_VALUE(msg_me, me_handle2, void *); + hlen2 = DM_GET_LEN(msg_me, me_handle2); + namp1 = DM_GET_VALUE(msg_me, me_name1, void *); + nlen1 = DM_GET_LEN(msg_me, me_name1); + namp2 = DM_GET_VALUE(msg_me, me_name2, void *); + nlen2 = DM_GET_LEN(msg_me, me_name2); + hanp3 = DM_GET_VALUE(msg_me, me_roothandle, void *); + hlen3 = DM_GET_LEN(msg_me, me_roothandle); + mode = msg_me->me_mode; +#endif /* VERITAS_21 */ + + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } else { + sprintf(hans1, "", hlen1); + } + if (hanp2 && hlen2) { + hantoa(hanp2, hlen2, hans2); + } else { + sprintf(hans2, "", hlen2); + } + if (hanp3 && hlen3) { + hantoa(hanp3, hlen3, hans3); + } else { + sprintf(hans3, "", hlen3); + } + if (namp1 && nlen1) { + strncpy(nams1, namp1, nlen1); + if (nlen1 != sizeof(nams1)) + nams1[nlen1] = '\0'; + } else { + sprintf(nams1, "", nlen1); + } + if (namp2 && nlen2) { + strncpy(nams2, namp2, nlen2); + if (nlen2 != sizeof(nams2)) + nams2[nlen2] = '\0'; + } else { + sprintf(nams2, "", nlen2); + } + + printf(VALS VALS VALS VALS VALS VALD, + "fs handle", hans1, + "mtpt handle", hans2, + "mtpt path", nams1, + "media desig", nams2, + "root handle", hans3, + "mode", mode); +} + + +static int +print_one_data_event( + dm_data_event_t *msg_de) +{ + char handle[HANDLE_STR]; + void *hanp; + size_t hlen; + + hanp = DM_GET_VALUE(msg_de, de_handle, void *); + hlen = DM_GET_LEN (msg_de, de_handle); + + if (hanp && hlen) { + hantoa(hanp, hlen, handle); + } else { + sprintf(handle, "", hlen); + } + + printf(VALS VALLLD VALLLD, + "file handle", handle, + "offset", msg_de->de_offset, + "length", msg_de->de_length); + + return(0); +} + + +int +print_one_message( + dm_eventmsg_t *msg) +{ + int pkt_error = 0; + int error; + dm_namesp_event_t *msg_ne; + void *hanp1, *hanp2, *namp1, *namp2; + u_int hlen1, hlen2, nlen1, nlen2; + char hans1[HANDLE_STR], hans2[HANDLE_STR]; + char nams1[MAXNAMELEN], nams2[MAXNAMELEN]; + + /***** USER EVENTS *****/ + + if (msg->ev_type == DM_EVENT_USER) { + char *privp; + u_int plen, i; + + printf(HDR, + "user", msg->ev_token, msg->ev_sequence); + + /* print private data as ascii or hex if it exists DM_CONFIG_MAX_MESSAGE_DATA */ + + privp = DM_GET_VALUE(msg, ev_data, char *); + plen = DM_GET_LEN (msg, ev_data); + if (plen) { + for (i = 0; i < plen; i++) { + if (!isprint(privp[i]) && !isspace(privp[i])) + break; + } + if (i == plen - 1 && privp[i] == '\0') { + printf(VALS, + "privdata", privp); + } else { + printf("\t%-15s ", "privdata"); + for (i = 0; i < plen; i++) { + printf("%.2x", privp[i]); + } + printf("\n"); + } + } else { + printf(VALS, + "privdata", ""); + } + + /***** CANCEL EVENT *****/ + +/* Not implemented on SGI or Veritas */ + + } else if (msg->ev_type == DM_EVENT_CANCEL) { + dm_cancel_event_t *msg_ce; + + msg_ce = DM_GET_VALUE(msg, ev_data, dm_cancel_event_t *); + printf(HDR VALD VALD, + "cancel", msg->ev_token, msg->ev_sequence, + "sequence", msg_ce->ce_sequence, + "token", msg_ce->ce_token); + + /***** DATA EVENTS *****/ + + } else if (msg->ev_type == DM_EVENT_READ || + msg->ev_type == DM_EVENT_WRITE || + msg->ev_type == DM_EVENT_TRUNCATE) { + dm_data_event_t *msg_de; + + msg_de = DM_GET_VALUE(msg, ev_data, dm_data_event_t *); + + switch (msg->ev_type) { + case DM_EVENT_READ: + printf(HDR, "read", msg->ev_token, msg->ev_sequence); + break; + + case DM_EVENT_WRITE: + printf(HDR, "write", msg->ev_token, msg->ev_sequence); + break; + + case DM_EVENT_TRUNCATE: + printf(HDR, "truncate", msg->ev_token, + msg->ev_sequence); + break; + } + print_one_data_event(msg_de); + + /***** DESTROY EVENT *****/ + + } else if (msg->ev_type == DM_EVENT_DESTROY) { + dm_destroy_event_t *msg_ds; + char attrname[DM_ATTR_NAME_SIZE + 1]; + u_char *copy; + u_int clen; + u_int i; + + msg_ds= DM_GET_VALUE(msg, ev_data, dm_destroy_event_t *); + hanp1 = DM_GET_VALUE(msg_ds, ds_handle, void *); + hlen1 = DM_GET_LEN (msg_ds, ds_handle); + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } else { + sprintf(hans1, "", hlen1); + } + if (msg_ds->ds_attrname.an_chars[0] != '\0') { + strncpy(attrname, (char *)msg_ds->ds_attrname.an_chars, sizeof(attrname)); + } else { + strcpy(attrname, ""); + } + printf(HDR VALS VALS, + "destroy", msg->ev_token, msg->ev_sequence, + "handle", hans1, + "attrname", attrname); + copy = DM_GET_VALUE(msg_ds, ds_attrcopy, u_char *); + clen = DM_GET_LEN (msg_ds, ds_attrcopy); + if (copy && clen) { + printf("\t%-15s ", "attrcopy"); + for (i = 0; i < clen; i++) { + printf("%.2x", copy[i]); + } + printf("\n"); + } else { + printf(VALS, "attrcopy", ""); + } + + /***** MOUNT EVENT *****/ + + } else if (msg->ev_type == DM_EVENT_MOUNT) { + void *msg_body; + + printf(HDR, "mount", msg->ev_token, msg->ev_sequence); +#if !VERITAS_21 + msg_body = DM_GET_VALUE(msg, ev_data, dm_mount_event_t *); +#else /* VERITAS_21 */ + msg_body = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *); +#endif /* VERITAS_21 */ + print_one_mount_event(msg_body); + + /***** NAMESPACE EVENTS *****/ + + } else { + char *type; + + msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *); + hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *); + hlen1 = DM_GET_LEN (msg_ne, ne_handle1); + hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *); + hlen2 = DM_GET_LEN (msg_ne, ne_handle2); + namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *); + nlen1 = DM_GET_LEN (msg_ne, ne_name1); + namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *); + nlen2 = DM_GET_LEN (msg_ne, ne_name2); + + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } + if (hanp2 && hlen2) { + hantoa(hanp2, hlen2, hans2); + } + if (namp1 && nlen1) { + strncpy(nams1, namp1, nlen1); + if (nlen1 != sizeof(nams1)) + nams1[nlen1] = '\0'; + } + if (namp2 && nlen2) { + strncpy(nams2, namp2, nlen2); + if (nlen2 != sizeof(nams2)) + nams2[nlen2] = '\0'; + } + + if (msg->ev_type == DM_EVENT_PREUNMOUNT || + msg->ev_type == DM_EVENT_UNMOUNT) { + if (msg_ne->ne_mode == 0) { + type = "NOFORCE"; +#if !VERITAS_21 + } else if (msg_ne->ne_mode == DM_UNMOUNT_FORCE) { +#else + } else if (msg_ne->ne_mode > 0) { +#endif + type = "FORCE"; + } else { + type = "UNKNOWN"; + pkt_error++; + } + } else if (msg->ev_type == DM_EVENT_CREATE || + msg->ev_type == DM_EVENT_POSTCREATE || + msg->ev_type == DM_EVENT_REMOVE || + msg->ev_type == DM_EVENT_POSTREMOVE) { + if (format_mode(msg_ne->ne_mode, &type)) { + pkt_error++; + } + } + + switch(msg->ev_type) { + + case DM_EVENT_PREUNMOUNT: + printf(HDR VALS VALS VALS, + "preunmount", msg->ev_token, msg->ev_sequence, + "fs handle", hans1, + "root dir", hans2, + "unmount mode", type); + break; + + case DM_EVENT_UNMOUNT: + printf(HDR VALS VALS VALD, + "unmount", msg->ev_token, msg->ev_sequence, + "fs handle", hans1, + "unmount mode", type, + "retcode", msg_ne->ne_retcode); + break; + + case DM_EVENT_NOSPACE: + printf(HDR VALS, + "nospace", msg->ev_token, msg->ev_sequence, + "fs handle", hans1); + break; + + case DM_EVENT_DEBUT: /* not supported on SGI */ + printf(HDR VALS, + "debut", msg->ev_token, msg->ev_sequence, + "object", hans1); + break; + + case DM_EVENT_CREATE: + printf(HDR VALS VALS VALS, + "create", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "mode bits", type); + break; + + case DM_EVENT_POSTCREATE: + printf(HDR VALS VALS VALS VALS VALD, + "postcreate", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "new object", hans2, + "name", nams1, + "mode bits", type, + "retcode", msg_ne->ne_retcode); + break; + + case DM_EVENT_REMOVE: + printf(HDR VALS VALS VALS, + "remove", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "mode bits", type); + break; + + case DM_EVENT_POSTREMOVE: + printf(HDR VALS VALS VALS VALD, + "postremove", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "mode bits", type, + "retcode", msg_ne->ne_retcode); + break; + + case DM_EVENT_RENAME: + printf(HDR VALS VALS VALS VALS, + "rename", msg->ev_token, msg->ev_sequence, + "old parent", hans1, + "new parent", hans2, + "old name", nams1, + "new name", nams2); + break; + + case DM_EVENT_POSTRENAME: + printf(HDR VALS VALS VALS VALS VALD, + "postrename", msg->ev_token, msg->ev_sequence, + "old parent", hans1, + "new parent", hans2, + "old name", nams1, + "new name", nams2, + "retcode", msg_ne->ne_retcode); + break; + + case DM_EVENT_SYMLINK: + printf(HDR VALS VALS VALS, + "symlink", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "contents", nams2); + break; + + case DM_EVENT_POSTSYMLINK: + printf(HDR VALS VALS VALS VALS VALD, + "postsymlink", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "new object", hans2, + "name", nams1, + "contents", nams2, + "retcode", msg_ne->ne_retcode); + break; + + case DM_EVENT_LINK: + printf(HDR VALS VALS VALS, + "link", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "source", hans2, + "name", nams1); + break; + + case DM_EVENT_POSTLINK: + printf(HDR VALS VALS VALS VALD, + "postlink", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "source", hans2, + "name", nams1, + "retcode", msg_ne->ne_retcode); + break; + + case DM_EVENT_ATTRIBUTE: + printf(HDR VALS, + "attribute", msg->ev_token, msg->ev_sequence, + "object", hans1); + break; + + case DM_EVENT_CLOSE: /* not supported on SGI */ + printf(HDR VALS, + "close", msg->ev_token, msg->ev_sequence, + "object", hans1); + break; + + default: + pkt_error++; + printf(HDR VALD, + "", msg->ev_token, msg->ev_sequence, + "ev_type", msg->ev_type); + break; + } + } + return(pkt_error); +} + + +int +handle_message( + dm_sessid_t sid, + dm_eventmsg_t *msg) +{ + int respond, response, respcode; + int error = 0; + + if (print_one_message(msg)) + error++; + + /* Set the defaults for responding to events. */ + + respond = 1; + response = DM_RESP_CONTINUE; + respcode = 0; + + /***** USER EVENTS *****/ + + switch (msg->ev_type) { + case DM_EVENT_USER: + if (msg->ev_token == DM_INVALID_TOKEN) + respond = 0; + break; + + case DM_EVENT_CANCEL: + case DM_EVENT_DESTROY: + case DM_EVENT_POSTCREATE: + case DM_EVENT_POSTREMOVE: + case DM_EVENT_POSTRENAME: + case DM_EVENT_POSTSYMLINK: + case DM_EVENT_POSTLINK: + case DM_EVENT_ATTRIBUTE: + case DM_EVENT_CLOSE: + respond = 0; + break; + + case DM_EVENT_MOUNT: + case DM_EVENT_READ: + case DM_EVENT_WRITE: + case DM_EVENT_TRUNCATE: + case DM_EVENT_PREUNMOUNT: + case DM_EVENT_UNMOUNT: + case DM_EVENT_DEBUT: + case DM_EVENT_CREATE: + case DM_EVENT_REMOVE: + case DM_EVENT_RENAME: + case DM_EVENT_SYMLINK: + case DM_EVENT_LINK: + break; + + case DM_EVENT_NOSPACE: + response = DM_RESP_ABORT; + respcode = ENOSPC; + break; + + default: + if (msg->ev_token == DM_INVALID_TOKEN) + respond = 0; + break; + } + + /* Respond to those messages which require a response. */ + + if (respond) { + if (dm_respond_event(sid, msg->ev_token, response, respcode, 0, 0)) { + errno_msg("Can't respond to event"); + } + } + return(error); +} diff --git a/dmapi/src/common/lib/stubs.c b/dmapi/src/common/lib/stubs.c new file mode 100644 index 000000000..3cfe27ca4 --- /dev/null +++ b/dmapi/src/common/lib/stubs.c @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#include +#include + + +/* See dmport.h for a description of why all these wrapper routines are + necessary. Because SGI defines stub routines for all functions it didn't + implement, no SGI-specific wrappers are required. +*/ + + +#ifdef VERITAS_21 + +/* The Veritas version of dm_downgrade_right has two additional parameters + not defined in the XDSM spec. Provide values that make dm_downgrade_right + work according to the spec. +*/ + +extern int +xvfs_dm_downgrade_right( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token) +{ +#undef dm_downgrade_right + return(dm_downgrade_right(sid, hanp, hlen, token, 0, DM_RIGHT_SHARED)); +} + + +/* The last byte in a Veritas handle is a 'pad' byte which they don't bother + to initialize to zero. As a result, you can't do binary compares of + two handles to see if they are the same. This stub (along with others) + forces the pad byte to zero so that binary compares are possible +*/ + +extern int +xvfs_dm_fd_to_handle( + int fd, + void **hanpp, + size_t *hlenp) +{ +#undef dm_fd_to_handle + int rc; + + if ((rc = dm_fd_to_handle(fd, hanpp, hlenp)) == 0) { + if (*hlenp == 16) { + char *cp = (char *)*hanpp; + cp[15] = '\0'; + } + } + return(rc); +} + + +/* The Veritas version of dm_get_config_events has a slightly different name. +*/ + +extern int +dm_get_config_events( + void *hanp, + size_t hlen, + u_int nelem, + dm_eventset_t *eventsetp, + u_int *nelemp) +{ + return(dm_get_config_event(hanp, hlen, nelem, eventsetp, nelemp)); +} + + +/* In version 2.1 uflags was defined as 'int nowait', so a value of zero in + this field means that the caller wants to wait. In XDSM this was reversed, + where if the bottom bit of uflags is set then the caller wants to wait. + This routine makes the conversion. +*/ + +extern int +xvfs_dm_get_events( + dm_sessid_t sid, + u_int maxmsgs, + u_int uflags, + size_t buflen, + void *bufp, + size_t *rlenp) +{ +#undef dm_get_events + int nowait = 1; + + if (uflags & DM_EV_WAIT) + nowait = 0; + + return(dm_get_events(sid, maxmsgs, nowait, buflen, bufp, rlenp)); +} + + +/* The Veritas version of dm_get_mountinfo has the parameters in a different + order than in the XDSM spec. Hide this in the wrapper. +*/ + +extern int +xvfs_dm_get_mountinfo( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + size_t buflen, + void *bufp, + size_t *rlenp) +{ +#undef dm_get_mountinfo + return(dm_get_mountinfo(sid, token, hanp, hlen, buflen, bufp, rlenp)); +} + + +/* Veritas does not support the dm_getall_disp function. Furthermore, their + dm_dispinfo_t structure is missing the _link field that is needed for the + DM_STEP_TO_NEXT() macro to work. +*/ + +extern int +dm_getall_disp( + dm_sessid_t sid, + size_t buflen, + void *bufp, + size_t *rlenp) +{ + return(ENOSYS); +} + + +/* Veritas does not support the dm_getall_dmattr function. Furthermore, their + dm_attrlist_t structure is missing the _link field that is needed for the + DM_STEP_TO_NEXT() macro to work. +*/ + +extern int +dm_getall_dmattr( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + size_t buflen, + void *bufp, + size_t *rlenp) +{ + return(ENOSYS); +} + + +/* Veritas does not support dm_handle_is_valid. We emulate it by checking + fields which have known values, as DMF uses this a lot. +*/ + +extern dm_boolean_t +dm_handle_is_valid( + void *hanp, + size_t hlen) +{ + char *cp = (char *)hanp; + + if (hlen != 16) { + return(DM_FALSE); + } + if (cp[15] != '\0') { + return(DM_FALSE); + } + switch (cp[14]) { + case 1: + case 2: + case 4: + break; + default: + return(DM_FALSE); + } + switch (cp[13]) { + case 0: + case 1: + break; + default: + return(DM_FALSE); + } + return(DM_TRUE); +} + + +/* Veritas uses a dev_t for their dm_fsid_t, and named their routines + accordingly. Hide this in the wrapper. Note that a dev_t is 32 bits + and the SGI dm_fsid_t is defined to be a uint64_t. If this gets to + be a problem (e.g. %x verus %llx), the Veritas dm_fsid_t could be made + to match SGI with a little casting here and there. +*/ + +extern int +dm_handle_to_fsid( + void *hanp, + size_t hlen, + dm_fsid_t *fsidp) +{ + dev_t dev; + + dev = dm_handle_to_dev(hanp, hlen); + *fsidp = (dm_fsid_t)dev; + return(0); +} + + +/* The Veritas dm_handle_to_fgen returns a long which is really the + file's generation number. dm_igen_t is typedef'd to be a long also, + so the cast here is safe. +*/ + +extern int +dm_handle_to_igen( + void *hanp, + size_t hlen, + dm_igen_t *igenp) +{ +#undef dm_handle_to_igen + long igen; + + igen = (dm_igen_t)dm_handle_to_fgen(hanp, hlen); + *igenp = (dm_igen_t)igen; + return(0); +} + + +/* Veritas uses a long for their dm_ino_t, which is really an ino_t. + Hide this in the wrapper. Note that a ino_t is 32 bits and the SGI + dm_ino_t is defined to be a uint64_t. If this gets to be a problem + (e.g. %x verus %llx), the Veritas dm_ino_t could be made to match SGI + with a little casting here and there. +*/ + + +extern int +xvfs_dm_handle_to_ino( + void *hanp, + size_t hlen, + dm_ino_t *inop) +{ +#undef dm_handle_to_ino + long ino; + + ino = (dm_ino_t)dm_handle_to_ino(hanp, hlen); + *inop = (dm_ino_t)ino; + return(0); +} + + +/* Version 2.1 of the spec did not specify the versionstrpp parameter. This + code makes the routine appear to work correctly to the caller, but it + is not really able to do the runtime check that the parameter is + supposed to provide. +*/ + +extern int +xvfs_dm_init_service( + char **versionstrpp) +{ +#undef dm_init_service + *versionstrpp = DM_VER_STR_CONTENTS; + return(dm_init_service()); +} + + +extern int +xvfs_dm_make_fshandle( + dm_fsid_t *fsidp, + void **hanpp, + size_t *hlenp) +{ +#undef dm_make_fshandle + dev_t dev; + + dev = (dev_t)*fsidp; + return(dm_make_fshandle(dev, hanpp, hlenp)); +} + + +extern int +xvfs_dm_make_handle( + dm_fsid_t *fsidp, + dm_ino_t *inop, + dm_igen_t *igenp, + void **hanpp, + size_t *hlenp) +{ +#undef dm_make_handle + dev_t dev; + long ino; + long igen; + + dev = (dev_t)*fsidp; + ino = (long)*inop; + igen = (long)*igenp; + return(dm_make_handle(dev, ino, igen, hanpp, hlenp)); +} + + +/* The last byte in a Veritas handle is a 'pad' byte which they don't bother + to initialize to zero. As a result, you can't do binary compares of + two handles to see if they are the same. This stub (along with others) + forces the pad byte to zero so that binary compares are possible +*/ + +extern int +xvfs_dm_path_to_fshandle( + char *path, + void **fshanpp, + size_t *fshlenp) +{ +#undef dm_path_to_fshandle + int rc; + + if ((rc = dm_path_to_fshandle(path, fshanpp, fshlenp)) == 0) { + if (*fshlenp == 16) { + char *cp = (char *)*fshanpp; + cp[15] = '\0'; + } + } + return(rc); +} + + +/* The last byte in a Veritas handle is a 'pad' byte which they don't bother + to initialize to zero. As a result, you can't do binary compares of + two handles to see if they are the same. This stub (along with others) + forces the pad byte to zero so that binary compares are possible +*/ + +extern int +xvfs_dm_path_to_handle( + char *path, + void **hanpp, + size_t *hlenp) +{ +#undef dm_path_to_handle + int rc; + + if ((rc = dm_path_to_handle(path, hanpp, hlenp)) == 0) { + if (*hlenp == 16) { + char *cp = (char *)*hanpp; + cp[15] = '\0'; + } + } + return(rc); +} + + +/* Veritas has a prototype for this function even though it is not + implemented. +*/ + +extern int +xvfs_dm_pending( + dm_sessid_t sid, + dm_token_t token, + dm_timestruct_t *delay) +{ +#undef dm_pending + return(ENOSYS); +} + + +extern int +xvfs_dm_read_invis( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_off_t off, + dm_size_t len, + void *bufp) +{ +#undef dm_read_invis + return(dm_read_invis(sid, hanp, hlen, token, off, (dm_ssize_t)len, bufp)); +} + + +/* In version 2.1 uflags was defined as 'int nowait', so a value of zero in + this field means that the caller wants to wait. In XDSM this was reversed, + where if the bottom bit of uflags is set then the caller wants to wait. + This routine makes the conversion. +*/ + +extern int +xvfs_dm_request_right( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int uflags, + dm_right_t right) +{ +#undef dm_request_right + int nowait = 1; + + if (uflags & DM_RR_WAIT) + nowait = 0; + return(dm_request_right(sid, hanp, hlen, token, nowait, right)); +} + + +extern int +xvfs_dm_set_inherit( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_attrname_t *attrnamep, + mode_t mode) +{ +#undef dm_set_inherit + return(dm_set_inherit(sid, hanp, hlen, token, attrnamep, (u_int)mode)); +} + + +extern int +xvfs_dm_set_region( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int nelem, + dm_region_t *regbufp, + dm_boolean_t *exactflagp) +{ +#undef dm_set_region + return(dm_set_region(sid, hanp, hlen, token, nelem, regbufp, (u_int *)exactflagp)); +} + + +extern int +dm_set_return_on_destroy( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_attrname_t *attrnamep, + dm_boolean_t enable) +{ + return(dm_set_return_ondestroy(sid, hanp, hlen, token, attrnamep, (int)enable)); +} + + +extern int +xvfs_dm_sync_by_handle( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token) +{ +#undef dm_sync_by_handle + return((int)dm_sync_by_handle(sid, hanp, hlen, token)); +} + +extern int +xvfs_dm_upgrade_right( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token) +{ +#undef dm_upgrade_right + return(dm_upgrade_right(sid, hanp, hlen, token, 0, DM_RIGHT_EXCL)); +} + + +extern int +xvfs_dm_write_invis( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + int flags, + dm_off_t off, + dm_size_t len, + void *bufp) +{ +#undef dm_write_invis + return(dm_write_invis(sid, hanp, hlen, token, off, (dm_ssize_t)len, bufp, flags)); +} + +#endif diff --git a/dmapi/src/common/lib/util.c b/dmapi/src/common/lib/util.c new file mode 100644 index 000000000..9e92eed4b --- /dev/null +++ b/dmapi/src/common/lib/util.c @@ -0,0 +1,1004 @@ +/* + * Utility routines + * + * This code was written by Peter Lawthers, and placed in the public + * domain for use by DMAPI implementors and app writers. + * + * Standard disclaimer: + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include + +#include + +#ifdef linux +#include +#define S_IAMB (S_IRWXU|S_IRWXG|S_IRWXO) +#endif + +#define S_MASK (S_ISUID|S_ISGID|S_ISVTX|S_IAMB) + +extern char *Progname; +extern int errno; + +void err_msg(char *, ...); +void errno_msg(char *, ...); + +struct ev_name_to_value ev_names[] = { + { "DM_EVENT_CANCEL", DM_EVENT_CANCEL }, + { "DM_EVENT_MOUNT", DM_EVENT_MOUNT }, + { "DM_EVENT_PREUNMOUNT", DM_EVENT_PREUNMOUNT }, + { "DM_EVENT_UNMOUNT", DM_EVENT_UNMOUNT }, + { "DM_EVENT_DEBUT", DM_EVENT_DEBUT }, + { "DM_EVENT_CREATE", DM_EVENT_CREATE }, + { "DM_EVENT_CLOSE", DM_EVENT_CLOSE }, + { "DM_EVENT_POSTCREATE", DM_EVENT_POSTCREATE }, + { "DM_EVENT_REMOVE", DM_EVENT_REMOVE }, + { "DM_EVENT_POSTREMOVE", DM_EVENT_POSTREMOVE }, + { "DM_EVENT_RENAME", DM_EVENT_RENAME }, + { "DM_EVENT_POSTRENAME", DM_EVENT_POSTRENAME }, + { "DM_EVENT_LINK", DM_EVENT_LINK }, + { "DM_EVENT_POSTLINK", DM_EVENT_POSTLINK }, + { "DM_EVENT_SYMLINK", DM_EVENT_SYMLINK }, + { "DM_EVENT_POSTSYMLINK", DM_EVENT_POSTSYMLINK }, + { "DM_EVENT_READ", DM_EVENT_READ }, + { "DM_EVENT_WRITE", DM_EVENT_WRITE }, + { "DM_EVENT_TRUNCATE", DM_EVENT_TRUNCATE }, + { "DM_EVENT_ATTRIBUTE", DM_EVENT_ATTRIBUTE }, + { "DM_EVENT_DESTROY", DM_EVENT_DESTROY }, + { "DM_EVENT_NOSPACE", DM_EVENT_NOSPACE }, + { "DM_EVENT_USER", DM_EVENT_USER } +}; + +int ev_namecnt = sizeof(ev_names) / sizeof(ev_names[0]); + +dm_eventtype_t +ev_name_to_value( + char *name) +{ + int i; + + for (i = 0; i < ev_namecnt; i++) { + if (!strcmp(name, ev_names[i].name)) + return(ev_names[i].value); + } + return(DM_EVENT_INVALID); +} + +char * +ev_value_to_name( + dm_eventtype_t event) +{ + static char buffer[100]; + int i; + + for (i = 0; i < ev_namecnt; i++) { + if (event == ev_names[i].value) + return(ev_names[i].name); + } + sprintf(buffer, "Unknown Event Number %d\n", event); + return(buffer); +} + + + +struct rt_name_to_value rt_names[] = { + { "DM_RIGHT_NULL", DM_RIGHT_NULL }, + { "DM_RIGHT_SHARED", DM_RIGHT_SHARED }, + { "DM_RIGHT_EXCL", DM_RIGHT_EXCL } +}; + +int rt_namecnt = sizeof(rt_names) / sizeof(rt_names[0]); + +int +rt_name_to_value( + char *name, + dm_right_t *rightp) +{ + int i; + + for (i = 0; i < rt_namecnt; i++) { + if (!strcmp(name, rt_names[i].name)) { + *rightp = rt_names[i].value; + return(0); + } + } + return(1); +} + + +char * +rt_value_to_name( + dm_right_t right) +{ + int i; + + for (i = 0; i < rt_namecnt; i++) { + if (right == rt_names[i].value) + return(rt_names[i].name); + } + return(NULL); +} + + +/* + * Convert a handle from (possibly) binary to ascii. + */ +void +hantoa( + void *hanp, + size_t hlen, + char *handle_str) +{ + int i; + u_char *cp; + + cp = (u_char *)hanp; + for (i=0;i HANDLE_LEN * 2){ + return(EBADF); + } + + while (*handle_str && *(handle_str + 1)) { + if (i == HANDLE_LEN){ + return(EBADF); + } + cur_char[0] = *handle_str; + cur_char[1] = *(handle_str + 1); + cur_char[2] = '\0'; + num = strtol(cur_char, (char **)0, 16); + handle[i++] = num & 0xff; + handle_str += 2; + } + if (*handle_str){ + return(EBADF); + } + *hlenp = i; + if ((*hanpp = malloc(*hlenp)) == NULL) + return(ENOMEM); + memcpy(*hanpp, handle, *hlenp); + return(0); +} + + +int +opaque_to_handle( + char *name, + void **hanpp, + size_t *hlenp) +{ + if (atohan(name, hanpp, hlenp)) { + /* not a handle */ + } else if (dm_handle_is_valid(*hanpp, *hlenp) == DM_FALSE) { + dm_handle_free(*hanpp, *hlenp); + /* not a handle */ + } else { + return(0); + } + + /* Perhaps it is a pathname */ + + if (dm_path_to_handle(name, hanpp, hlenp)) { + return(errno); + } + return(0); +} + + +void +print_handle( + void *hanp, + size_t hlen) +{ + char handle_str[HANDLE_STR]; + + if (hlen > HANDLE_LEN) { + printf("-- invalid hlen length %d --\n", hlen); + return; + } + + printf("print_handle: "); + printf("%d\t", hlen); + hantoa(hanp, hlen, handle_str); + printf("%s\n ", handle_str); +} + +void +print_victim( + void *hanp, + size_t hlen, + dm_off_t fsize) +{ + char handle_str[HANDLE_STR]; + + if (hlen > HANDLE_LEN) { + printf("-- invalid length --\n"); + return; + } + + printf("%d\t", hlen); + hantoa(hanp, hlen, handle_str); + printf("%s ", handle_str); +#ifdef __sgi + printf("\t%lld \n", fsize); +#else + printf("\t%ld \n", fsize); +#endif +} + + +/* + * Print out a simple error message, and include the errno + * string with it. + */ +void +errno_msg(char *fmt, ...) +{ + va_list ap; + int old_errno; + + old_errno = errno; + fprintf(stderr, "%s: ", Progname); + + va_start(ap, fmt ); + vfprintf(stderr, fmt, ap); + va_end(ap); + + errno = old_errno; + perror("\n\tError"); +} + +/* + * Print out a simple error message + */ +void +err_msg(char *fmt, ...) +{ + va_list ap; + + fprintf(stderr, "%s: ", Progname); + + va_start(ap, fmt ); + vfprintf(stderr, fmt, ap); + va_end(ap); + +} + + +/* + * Initialize the interface to the DMAPI + */ +int +setup_dmapi(dm_sessid_t *sidp) +{ + char *cp; + + if (dm_init_service(&cp) == -1) { + err_msg("%s/%d: Can't init dmapi", __FILE__, __LINE__); + return(1); + } + if (strcmp(cp, DM_VER_STR_CONTENTS)) { + err_msg("%s/%d: Compiled for a different version", __FILE__, __LINE__); + return(1); + } + + find_test_session(sidp); + return(0); +} + +/* + * Get the file's change indicator + */ +int +get_dmchange( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + u_int *change_start) +{ + int error; + dm_stat_t statbuf; + + + error = dm_get_fileattr(sid, hanp, hlen, token, DM_AT_CFLAG, &statbuf); + if (error == -1) { + errno_msg("%s/%d: Can't stat file (%d)", __FILE__, __LINE__, errno); + return(1); + } + *change_start = statbuf.dt_change; + return(0); +} + + +/* + * Write a file's data to the staging file. We write the file out + * in 4meg chunks. + */ +int +save_filedata( + dm_sessid_t sid, + void *hanp, + size_t hlen, + int stg_fd, + dm_size_t fsize) +{ + char *filebuf; + int i, nbufs; + int retval; + dm_ssize_t nread, lastbuf; + ssize_t nwrite; + dm_off_t off; + + nbufs = fsize / CHUNKSIZE; + off = 0; + retval = 0; + filebuf = malloc(CHUNKSIZE); + if (filebuf == NULL) { + err_msg("%s/%d: Can't alloc memory for file buffer", __FILE__, __LINE__); + goto out; + } + + for (i = 0; idt_dev != statb.st_dev) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_dev 0x%x, " + "statb.st_dev 0x%x\n", dmstat->dt_dev, + statb.st_dev); + } + errors++; + } + if (dmstat->dt_ino != statb.st_ino) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_ino %llx, " +#if defined(__sgi) && (_MIPS_SIM != _MIPS_SIM_ABI32) + "statb.st_ino %llx\n", +#else + "statb.st_ino %x\n", +#endif + dmstat->dt_ino, statb.st_ino); + } + errors++; + } + if ((dmstat->dt_mode & S_IFMT) != field_to_mode(statb.st_mode)) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_mode (mode) %s, " + "statb.st_mode (mode) %s\n", + mode_to_string(dmstat->dt_mode), + mode_to_string(field_to_mode(statb.st_mode))); + } + errors++; + } + if ((dmstat->dt_mode & S_MASK) != (statb.st_mode & S_MASK)) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_mode (perm) 0%o, " + "statb.st_mode (perm) 0%o\n", + dmstat->dt_mode & S_MASK, + statb.st_mode & S_MASK); + } + errors++; + } + if (dmstat->dt_nlink != statb.st_nlink) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_nlink %d, " + "statb.st_nlink %d\n", dmstat->dt_nlink, + statb.st_nlink); + } + errors++; + } + if (dmstat->dt_uid != statb.st_uid) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_uid %d, " + "statb.st_uid %d\n", dmstat->dt_uid, + statb.st_uid); + } + errors++; + } + if (dmstat->dt_gid != statb.st_gid) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_gid %d, " + "statb.st_gid %d\n", dmstat->dt_gid, + statb.st_gid); + } + errors++; + } + if (dmstat->dt_rdev != statb.st_rdev) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_rdev 0x%x, " + "statb.st_rdev 0x%x\n", dmstat->dt_rdev, + statb.st_rdev); + } + errors++; + } + if (dmstat->dt_size != statb.st_size) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_size %lld, " +#if defined(__sgi) && (_MIPS_SIM != _MIPS_SIM_ABI32) + "statb.st_size %lld\n", +#else + "statb.st_size %d\n", +#endif + dmstat->dt_size, statb.st_size); + } + errors++; + } + if (dmstat->dt_atime != statb.st_atime) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_atime %d, " + "statb.st_atime %d\n", dmstat->dt_atime, + statb.st_atime); + } + errors++; + } + if (dmstat->dt_mtime != statb.st_mtime) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_mtime %d, " + "statb.st_mtime %d\n", dmstat->dt_mtime, + statb.st_mtime); + } + errors++; + } + if (dmstat->dt_ctime != statb.st_ctime) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_ctime %d, " + "statb.st_ctime %d\n", dmstat->dt_ctime, + statb.st_ctime); + } + errors++; + } + if (dmstat->dt_dtime != statb.st_ctime) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_dtime %d, " + "statb.st_ctime %d\n", dmstat->dt_dtime, + statb.st_ctime); + } + errors++; + } + if (dmstat->dt_blksize != statb.st_blksize) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_blksize %d, " + "statb.st_blksize %d\n", dmstat->dt_blksize, + statb.st_blksize); + } + errors++; + } + if (dmstat->dt_blocks != statb.st_blocks) { + if (report_errors) { + fprintf(stdout, "ERROR:dmstat->dt_blocks %lld, " +#if defined(__sgi) && (_MIPS_SIM != _MIPS_SIM_ABI32) + "statb.st_blocks %lld\n", +#else + "statb.st_blocks %d\n", +#endif + dmstat->dt_blocks, statb.st_blocks); + } + errors++; + } + + if (errors && report_errors) + fprintf(stdout, "There were %d differences\n", errors); + return(errors); +} + + +extern char * +date_to_string( + time_t timeval) +{ +static char buffer[21]; + char *tmstr; + + if (timeval == (time_t)0) { + strcpy(buffer, "0"); + } else { + tmstr = asctime(localtime(&timeval)); + tmstr += 4; + strncpy(buffer, tmstr, 20); + buffer[20] = '\0'; + } + return(buffer); +} + + +extern char * +mode_to_string( + mode_t mode) +{ +static char buffer[256]; + + switch (mode & S_IFMT) { + + case S_IFBLK: + return("S_IFBLK"); + + case S_IFREG: + return("S_IFREG"); + + case S_IFDIR: + return("S_IFDIR"); + + case S_IFCHR: + return("S_IFCHR"); + + case S_IFIFO: + return("S_IFIFO"); + + case S_IFLNK: + return("S_IFLNK"); + + case S_IFSOCK: + return("S_IFSOCK"); + + default: + sprintf(buffer, "Invalid mode 0%o", mode & S_IFMT); + return(buffer); + } +} + + +extern char * +emask_to_string( + dm_eventset_t emask) +{ +static char buffer[256]; + char *name; + int len = 0; + int i; + + for (i = 0; i < 32; i++) { + if (!DMEV_ISSET(i, emask)) + continue; + + switch (i) { + case DM_EVENT_CREATE: + name = "DM_EVENT_CREATE"; + break; + case DM_EVENT_POSTCREATE: + name = "DM_EVENT_POSTCREATE"; + break; + case DM_EVENT_REMOVE: + name = "DM_EVENT_REMOVE"; + break; + case DM_EVENT_POSTREMOVE: + name = "DM_EVENT_POSTREMOVE"; + break; + case DM_EVENT_RENAME: + name = "DM_EVENT_RENAME"; + break; + case DM_EVENT_POSTRENAME: + name = "DM_EVENT_POSTRENAME"; + break; + case DM_EVENT_LINK: + name = "DM_EVENT_LINK"; + break; + case DM_EVENT_POSTLINK: + name = "DM_EVENT_POSTLINK"; + break; + case DM_EVENT_SYMLINK: + name = "DM_EVENT_SYMLINK"; + break; + case DM_EVENT_POSTSYMLINK: + name = "DM_EVENT_POSTSYMLINK"; + break; + case DM_EVENT_READ: + name = "DM_EVENT_READ"; + break; + case DM_EVENT_WRITE: + name = "DM_EVENT_WRITE"; + break; + case DM_EVENT_TRUNCATE: + name = "DM_EVENT_TRUNCATE"; + break; + case DM_EVENT_ATTRIBUTE: + name = "DM_EVENT_ATTRIBUTE"; + break; + case DM_EVENT_DESTROY: + name = "DM_EVENT_DESTROY"; + break; + default: + fprintf(stderr, "Unknown event type %d\n", i); + exit(1); + } + sprintf(buffer + len, "%c%s", (len ? '|' : '('), name); + len = strlen(buffer); + } + + if (len == 0) { + sprintf(buffer, "(none)"); + } else { + sprintf(buffer + len, ")"); + } + return(buffer); +} + + +#if defined(__sgi) || defined(linux) + +extern char * +xflags_to_string( + u_int xflags) +{ +static char buffer[256]; + int len = 0; + + if (xflags & ~(DM_XFLAG_REALTIME|DM_XFLAG_PREALLOC|DM_XFLAG_HASATTR)) { + sprintf(buffer, "Invalid xflags 0%o", xflags); + return(buffer); + } + + if (xflags & DM_XFLAG_REALTIME) { + sprintf(buffer + len, "%cREALTIME", (len ? '|' : '(')); + len = strlen(buffer); + } + if (xflags & DM_XFLAG_PREALLOC) { + sprintf(buffer + len, "%cPREALLOC", (len ? '|' : '(')); + len = strlen(buffer); + } + if (xflags & DM_XFLAG_HASATTR) { + sprintf(buffer + len, "%cHASATTR", (len ? '|' : '(')); + len = strlen(buffer); + } + if (len == 0) { + sprintf(buffer, "(none)"); + } else { + sprintf(buffer + len, ")"); + } + return(buffer); +} + +#endif + + +extern void +print_state( + dm_stat_t *dmstat) +{ + /* Print all the stat block fields. */ + + fprintf(stdout, "dt_dev 0x%x\n", dmstat->dt_dev); +#ifdef __sgi + fprintf(stdout, "dt_ino %llx\n", dmstat->dt_ino); +#else + fprintf(stdout, "dt_ino %x\n", dmstat->dt_ino); +#endif + fprintf(stdout, "dt_mode (type) %s\n", + mode_to_string(dmstat->dt_mode)); + fprintf(stdout, "dt_mode (perm) 0%o\n", dmstat->dt_mode & S_MASK); + fprintf(stdout, "dt_nlink %d\n", dmstat->dt_nlink); + fprintf(stdout, "dt_uid %d\n", dmstat->dt_uid); + fprintf(stdout, "dt_gid %d\n", dmstat->dt_gid); + fprintf(stdout, "dt_rdev 0x%x\n", dmstat->dt_rdev); +#ifdef __sgi + fprintf(stdout, "dt_size %lld\n", dmstat->dt_size); +#else + fprintf(stdout, "dt_size %d\n", dmstat->dt_size); +#endif + + fprintf(stdout, "dt_atime %s\n", + date_to_string(dmstat->dt_atime)); + fprintf(stdout, "dt_mtime %s\n", + date_to_string(dmstat->dt_mtime)); + fprintf(stdout, "dt_ctime %s\n", + date_to_string(dmstat->dt_ctime)); + + fprintf(stdout, "dt_blksize %d\n", dmstat->dt_blksize); +#ifdef __sgi + fprintf(stdout, "dt_blocks %lld\n", dmstat->dt_blocks); +#else + fprintf(stdout, "dt_blocks %d\n", dmstat->dt_blocks); +#endif + +#if defined(__sgi) || defined(linux) + fprintf(stdout, "dt_xfs_igen %d\n", dmstat->dt_xfs_igen); + fprintf(stdout, "dt_xfs_xflags %s\n", + xflags_to_string(dmstat->dt_xfs_xflags)); + fprintf(stdout, "dt_xfs_extsize %d\n", dmstat->dt_xfs_extsize); + fprintf(stdout, "dt_xfs_extents %d\n", dmstat->dt_xfs_extents); + fprintf(stdout, "dt_xfs_aextents %d\n", dmstat->dt_xfs_aextents); +#endif + + fputc('\n', stdout); + + /* Print all other fields. */ + + fprintf(stdout, "emask %s\n", + emask_to_string(dmstat->dt_emask)); + fprintf(stdout, "nevents %d\n", dmstat->dt_nevents); + fprintf(stdout, "pmanreg %d\n", dmstat->dt_pmanreg); + fprintf(stdout, "pers %d\n", dmstat->dt_pers); + fprintf(stdout, "dt_dtime %s\n", + date_to_string(dmstat->dt_dtime)); + fprintf(stdout, "change %d\n", dmstat->dt_change); +} + + +extern void +print_line( + dm_stat_t *dmstat) +{ + fprintf(stdout, "0x%x|", dmstat->dt_dev); +#ifdef __sgi + fprintf(stdout, "%llx|", dmstat->dt_ino); +#else + fprintf(stdout, "%x|", dmstat->dt_ino); +#endif + fprintf(stdout, "%s|", mode_to_string(dmstat->dt_mode)); + fprintf(stdout, "0%o|", dmstat->dt_mode & S_MASK); + fprintf(stdout, "%d|", dmstat->dt_nlink); + fprintf(stdout, "%d|", dmstat->dt_uid); + fprintf(stdout, "%d|", dmstat->dt_gid); + fprintf(stdout, "0x%x|", dmstat->dt_rdev); +#ifdef __sgi + fprintf(stdout, "%lld|", dmstat->dt_size); +#else + fprintf(stdout, "%d|", dmstat->dt_size); +#endif + + fprintf(stdout, "%s|", date_to_string(dmstat->dt_atime)); + fprintf(stdout, "%s|", date_to_string(dmstat->dt_mtime)); + fprintf(stdout, "%s|", date_to_string(dmstat->dt_ctime)); + + fprintf(stdout, "%d|", dmstat->dt_blksize); +#ifdef __sgi + fprintf(stdout, "%lld|", dmstat->dt_blocks); +#else + fprintf(stdout, "%d|", dmstat->dt_blocks); +#endif + +#ifdef __sgi + fprintf(stdout, "%d|", dmstat->dt_xfs_igen); + fprintf(stdout, "%s|", xflags_to_string(dmstat->dt_xfs_xflags)); + fprintf(stdout, "%d|", dmstat->dt_xfs_extsize); + fprintf(stdout, "%d|", dmstat->dt_xfs_extents); + fprintf(stdout, "%d|", dmstat->dt_xfs_aextents); +#endif + + /* Print all other fields. */ + + fprintf(stdout, "%s|", emask_to_string(dmstat->dt_emask)); + fprintf(stdout, "%d|", dmstat->dt_nevents); + fprintf(stdout, "%d|", dmstat->dt_pmanreg); + fprintf(stdout, "%d|", dmstat->dt_pers); + fprintf(stdout, "%s|", date_to_string(dmstat->dt_dtime)); + fprintf(stdout, "%d", dmstat->dt_change); + + fputc('\n', stdout); +} diff --git a/dmapi/src/sample_hsm/README b/dmapi/src/sample_hsm/README new file mode 100644 index 000000000..0648f81e0 --- /dev/null +++ b/dmapi/src/sample_hsm/README @@ -0,0 +1,62 @@ +The files in this directory comprise a simple HSM example that uses +the DMAPI. These files are distributed in the hope that they will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. These programs +have been tested on an SGI platform (as of April 1995) and found +to be suitably functional; however, there is no guarantee that they +do, in fact, provide the functationality that is advertised. This +is a long winded way of saying they probably have bugs; if you +find 'em, fix 'em. + +Okay, now that we have the disclaimers out of the way, here are the details. + + migfind + ======= +This will find all files of a specified size, and print out the handles. +It is normally used like this: + migfind -s 800k /migfs >& cand_file + +This example will find all files greater than 800K in the /migfs filesystem, +and put the handles (converted to ascii) in the file 'cand_file'. The output +consists of three fields per line: + handle length filehandle file size in bytes + + migout + ====== +migout reads a list of handles as created by migfind, and migrates +the files data. The data is stored in files that are located in +another directory. The usage is + migout /dmapi_fs/stagedir < cand_file + +This will all the files specified by handle in 'cand_file', and +put their data in files located under the directory /dmapi_fs/stagedir'. +The staging directory must be on a filesystem that supports +the dmapi; the reason for this is to allow for a simplification +in the code that stores the location of the data as a DM attribute +(file handles are easier than path names). + + migin + ===== +This daemon waits for DMAPI events and dispatches worker bees +to actually stage the data in. The usage is: + migin -l dmapi_log /migfs +migin will fork/exec a 'wbee' to either bring the data back from +the staging directory, or to invalidate the file. + + +Other programs: +There are a couple of other programs in this directory. + + mrmean + ====== +Simplist cleanup/debugging tool that will print information about +the active sessions. If desired, it can also respond to outstanding +events and destroy sessions that may have been left around from +a process exiting unexpectedly. + + mls + === +Simple ls type program to display information about a file, such +as the managed region info, allocation info, event lists, and +file handle. + diff --git a/dmapi/src/sample_hsm/migfind.c b/dmapi/src/sample_hsm/migfind.c new file mode 100644 index 000000000..afd24f8ea --- /dev/null +++ b/dmapi/src/sample_hsm/migfind.c @@ -0,0 +1,286 @@ +/* + * Simple utility to find all files above a certain size in + * a filesystem. The output is to stdout, and is of the form: + * filehandle length filehandle file size in bytes + * + * The list is not sorted in any way. + * + * This code was written by Peter Lawthers, and placed in the public + * domain for use by DMAPI implementors and app writers. + * + * Standard disclaimer: + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include + +#include + +#define NUMLEN 16 /* arbitrary max len of input size */ +#define MAX_K (((u_int)LONG_MAX + 1) / 1024) +#define MAX_M (((u_int)LONG_MAX + 1) / (1024*1024)) + + + +extern char *optarg; +extern int optind, optopt, opterr; +char *Progname; + +extern void print_victim(void *, size_t, dm_off_t); +extern void err_msg(char *, ...); +extern void errno_msg(char *, ...); + +int setup_dmapi(dm_sessid_t *); +int scan_fs(dm_sessid_t, void *, size_t, dm_off_t); +int verify_size(char *, dm_off_t *); +void usage(char *); + +void +usage( + char *prog) +{ + fprintf(stderr, "Usage: %s ", prog); + fprintf(stderr, " [-s file threshold]"); + fprintf(stderr, " filesystem\n"); +} + +/* + * Convert an input string on the form 10m or 128K to something reasonable + */ +int +verify_size( + char *str, + dm_off_t *sizep) +{ + char *cp; + dm_off_t size; + + if (strlen(str) > NUMLEN) { + printf("Size %s is invalid \n", str); + return(1); + } + + size = strtol(str,0,0); + if (size < 0 || size >= LONG_MAX ) { + printf("Size %d is invalid \n", size); + return(1); + } + + cp = str; + while (isdigit(*cp)) + cp++; + if (*cp == 'k' || *cp == 'K') { + if ( size >= (u_int) MAX_K) { +#ifdef __sgi + printf("Size %lld is invalid\n", size); +#else + printf("Size %ld is invalid\n", size); +#endif + return(1); + } + size *= 1024; + } else if (*cp == 'm' || *cp == 'M') { + if ( size >= (u_int) MAX_M) { +#ifdef __sgi + printf("Size %lld is invalid\n", size); +#else + printf("Size %ld is invalid\n", size); +#endif + return(1); + } + size *= (1024*1024); + } + *sizep = size; + return(0); +} + + + +int +main( + int argc, + char *argv[]) +{ + + int c; + int error; + dm_off_t size; + char *fsname; + dm_sessid_t sid; + void *fs_hanp; + size_t fs_hlen; + char *sizep = "0"; + + + Progname = argv[0]; + size = 0; + + while ((c = getopt(argc, argv, "s:")) != EOF) { + switch (c) { + case 's': + sizep = optarg; + break; + + case '?': + default: + usage(Progname); + exit(1); + } + } + if (optind >= argc) { + usage(Progname); + exit(1); + } + /* + * Verify the input size string is legit + */ + error = verify_size(sizep, &size); + if (error) + exit(1); + + fsname = argv[optind]; + + /* + * Now we have our filesystem name and possibly a size threshold + * to look for. Init the dmapi, and get a filesystem handle so + * we can scan the filesystem + */ + error = setup_dmapi(&sid); + if (error) + exit(1); + + if (dm_path_to_fshandle(fsname, &fs_hanp, &fs_hlen) == -1) { + errno_msg("Can't get filesystem handle"); + exit(1); + } + + + + /* + * Get the attributes of all files in the filesystem + */ + error = scan_fs(sid, fs_hanp, fs_hlen, size); + if (error) + exit(1); + + + /* + * We're done, so we can shut down our session. + */ + if (dm_destroy_session(sid) == -1) { + errno_msg("Can't close session"); + exit(1); + } + + return(0); + +} + +/* + * Get the attributes for all the files in a filesystem in bulk, + * and print out the handles and sizes of any that meet our target + * criteria. + * + * We are not interested in file names; if we were, then we would + * have to do a dm_get_dirattrs() on each directroy, then use + * dm_handle_to_path() to get the pathname. + */ +int +scan_fs( + dm_sessid_t sid, + void *fs_hanp, + size_t fs_hlen, + dm_off_t target_size) +{ + u_int mask; /* attributes to scan for */ + dm_stat_t *dm_statbuf, *sbuf; /* attributes buffer */ + dm_attrloc_t locp; /* opaque location in fs */ + size_t rlenp; /* ret length of stat info */ + size_t buflen; /* length of stat buffer */ + void *hanp; /* file handle */ + size_t hlen; /* file handle */ + int more; /* loop terminator */ + int error; + + + /* + * Size the stat buffer to return info on 1K files at a time + */ + buflen = sizeof(dm_stat_t) * 1024; +#ifdef VERITAS_21 + if (buflen > 65536) + buflen = 65536; +#endif + dm_statbuf = (dm_stat_t *)calloc(1, buflen); + if (dm_statbuf == NULL) { + err_msg("Can't get memory for stat buffer"); + return(1); + } + + + /* + * Initialize the offset opaque offset cookie that + * we use in successive calls to dm_get_bulkattr() + */ + error = dm_init_attrloc(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, &locp); + if (error == -1) { + errno_msg("%s/%d: Can't initialize offset cookie (%d)", __FILE__, __LINE__, errno); + free(dm_statbuf); + return(1); + } + + /* + * Set our stat mask so that we'll only get the normal stat(2) + * info and the file's handle + */ + mask = DM_AT_HANDLE | DM_AT_STAT; + do { + more = dm_get_bulkattr(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, + mask, &locp, buflen, dm_statbuf, &rlenp); + if (more == -1) { + errno_msg("%s/%d: Can't get bulkattr for filesystem", __FILE__, __LINE__, errno); + break; + } + + /* + * Walk through the stat buffer and pull out files + * that are of interest + * + * The stat buffer is variable length, so we must + * use the DM_STEP_TO_NEXT macro to access each individual + * dm_stat_t structure in the returned buffer. + */ + sbuf = dm_statbuf; + while (sbuf != NULL) { + if (S_ISREG(sbuf->dt_mode) && + sbuf->dt_size >= target_size) { + hanp = DM_GET_VALUE(sbuf, dt_handle, void *); + hlen = DM_GET_LEN(sbuf, dt_handle); + + print_victim(hanp, hlen, sbuf->dt_size); + } + sbuf = DM_STEP_TO_NEXT(sbuf, dm_stat_t *); + } + } while (more == 1); + + free(dm_statbuf); + if (more == -1) + return(1); + + return(0); +} + diff --git a/dmapi/src/sample_hsm/migin.c b/dmapi/src/sample_hsm/migin.c new file mode 100644 index 000000000..32551f00a --- /dev/null +++ b/dmapi/src/sample_hsm/migin.c @@ -0,0 +1,488 @@ +/* + * Master migration daemon + * + * The master migration daemon waits for events on a file and + * spawns a child process to handle the event + * + * This code was written by Peter Lawthers, and placed in the public + * domain for use by DMAPI implementors and app writers. + * + * Standard disclaimer: + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern char *optarg; +extern int optind, optopt, opterr; +extern int errno; +char *Progname; +int Verbose; + +extern int setup_dmapi(dm_sessid_t *); +extern void err_msg(char *, ...); +extern void errno_msg(char *, ...); + +void event_loop(dm_sessid_t); +int set_events(dm_sessid_t, void *, size_t); +int mk_daemon(char *); +void spawn_kid(dm_sessid_t, dm_token_t, char *); +void migin_exit(void); +void usage(char *); + + +void +usage( + char *prog) +{ + fprintf(stderr, "Usage: %s ", prog); + fprintf(stderr, " <-v verbose> "); + fprintf(stderr, " <-l logfile> "); + fprintf(stderr, "filesystem \n"); +} + + +int +main( + int argc, + char *argv[]) +{ + + int c; + int error; + char *fsname, *logfile; + dm_sessid_t sid; + void *fs_hanp; + size_t fs_hlen; + + + Progname = argv[0]; + fsname = NULL; + logfile = NULL; + + while ((c = getopt(argc, argv, "vl:")) != EOF) { + switch (c) { + case 'v': + Verbose = 1; + break; + case 'l': + logfile = optarg; + break; + case '?': + default: + usage(Progname); + exit(1); + } + } + if (optind >= argc) { + usage(Progname); + exit(1); + } + fsname = argv[optind]; + if (fsname == NULL) { + usage(Progname); + exit(1); + } + /* + * If no logfile name is specified, we'll just send + * all output to some file in /tmp + */ + if (logfile == NULL) + logfile = LOG_DEFAULT; + + + /* + * Now we have our filesystem name and possibly a size threshold + * to look for. Init the dmapi, and get a filesystem handle so + * we can set up our events + */ + error = setup_dmapi(&sid); + if (error) + exit(1); + + if (dm_path_to_fshandle(fsname, &fs_hanp, &fs_hlen) == -1) { + errno_msg("Can't get filesystem handle"); + exit(1); + } + + /* + * Turn ourselves into a daemon + */ + error = mk_daemon(logfile); + if (error) + exit(1); + + + /* + * Set the event disposition so that our session will receive + * the managed region events (read, write, and truncate) + */ + error = set_events(sid, fs_hanp, fs_hlen); + if (error) + exit(1); + + + /* + * Now wait forever for messages, spawning kids to + * do the actual work + */ + event_loop(sid); + return(0); +} + +/* + * Main event loop processing + */ +void +event_loop( + dm_sessid_t sid) +{ + void *msgbuf; + size_t bufsize, rlen; + int error; + dm_eventmsg_t *msg; + + /* + * We take a swag at a buffer size. If it's wrong, we can + * always resize it + */ + bufsize = sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + HANDLE_LEN; + bufsize *= 16; + msgbuf = (void *)malloc(bufsize); + if (msgbuf == NULL) { + err_msg("Can't allocate memory for buffer"); + goto out; + } + + for (;;) { + error = dm_get_events(sid, ALL_AVAIL_MSGS, DM_EV_WAIT, bufsize, + msgbuf, &rlen); + if (error == -1) { + if (errno == E2BIG) { + free(msgbuf); + msgbuf = (void *)malloc(rlen); + if (msgbuf == NULL) { + err_msg("Can't resize msg buffer"); + goto out; + } + continue; + } + errno_msg("Error getting events from DMAPI"); + goto out; + } + + /* + * Walk thru the message buffer, pull out each individual + * message, and dispatch the messages to child processes + * with the sid, token, and data. The children will + * respond to the events. + */ + msg = (dm_eventmsg_t *)msgbuf; + while (msg != NULL ) { + if (Verbose) { + fprintf(stderr, "Received %s, token %d\n", + (msg->ev_type == DM_EVENT_READ ? "read" : + (msg->ev_type == DM_EVENT_WRITE ? "write" : "trunc")), msg->ev_token); + } + switch (msg->ev_type) { + + case DM_EVENT_READ: + spawn_kid(sid, msg->ev_token, RESTORE_FILE); + break; + + case DM_EVENT_WRITE: + case DM_EVENT_TRUNCATE: + spawn_kid(sid, msg->ev_token, INVAL_FILE); + break; + + default: + err_msg("Invalid msg type %d\n", msg->ev_type); + break; + } + msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *); + } + } +out: + if (msgbuf != NULL) + free(msgbuf); + + migin_exit(); +} + +/* + * Fork and exec our worker bee to work on the file. If + * there is any error in fork/exec'ing the file, we have to + * supply the error return to the event. Once the child gets + * started, he/she/it will respond to the event for us. + */ +void +spawn_kid( + dm_sessid_t sid, + dm_token_t token, + char *action) +{ + pid_t pid; + char sidbuf[sizeof(dm_sessid_t)]; + char tokenbuf[sizeof(dm_token_t)]; + + pid = fork(); + if (pid == 0) { + /* + * We're in the child. Try and exec the worker bee + */ + sprintf(sidbuf, "%d", sid); + sprintf(tokenbuf, "%d", token); + if (Verbose) { + fprintf(stderr, "execl(%s, %s, %s, -s, %s, -t, xs, 0)\n", + WORKER_BEE, WORKER_BEE, action, sidbuf, tokenbuf); + } + if (execl(WORKER_BEE, WORKER_BEE, action, "-s", sidbuf, + "-t", tokenbuf, NULL)) + { + (void)dm_respond_event(sid, token, DM_RESP_ABORT, + errno, 0, 0); + exit(1); + } + } + + if (pid < 0) { + err_msg("Can't fork worker bee"); + (void)dm_respond_event(sid, token, DM_RESP_ABORT, errno, + 0, 0); + return; + } + return; + +} + + +/* + * Set the event disposition of the managed region events + */ +int +set_events( + dm_sessid_t sid, + void *fs_hanp, + size_t fs_hlen) +{ + dm_eventset_t eventlist; + + DMEV_ZERO(eventlist); + DMEV_SET(DM_EVENT_READ, eventlist); + DMEV_SET(DM_EVENT_WRITE, eventlist); + DMEV_SET(DM_EVENT_TRUNCATE, eventlist); + + if (dm_set_disp(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, &eventlist, + DM_EVENT_MAX) == -1) + { + errno_msg("Can't set event disposition"); + return(1); + } + return(0); +} + + + + +/* + * Dissassociate ourselves from our tty, and close all files + */ +int +mk_daemon( + char *logfile) +{ + int fd, pid; + int i; + struct rlimit lim; + struct sigaction act; + +#ifdef NOTYET + if ((pid = fork()) == -1) + return (-1); + if (pid) + exit(0); + + (void) setsid(); + + (void) chdir("/"); + +#endif /* NOTYET */ + /* + * Determine how many open files we've got and close + * then all + */ + if (getrlimit(RLIMIT_NOFILE, &lim) < 0 ) { + errno_msg("Can't determine max number of open files"); + return(1); + } + for (i=0; i 0) + ; + + fprintf(stdout, "\n"); + + /* + * Now search for our session and try and shut it down. We + * could just as easily make the session ID a global, but + * this demonstrates how sessions can be queried + */ + nsessions = 4; + sidbuf = (dm_sessid_t *)malloc(nsessions * sizeof(dm_sessid_t)); + if (sidbuf == NULL) { + err_msg("Can't alloc mem to shut down session"); + goto out; + } + error = dm_getall_sessions(nsessions, sidbuf, &nret); + if (error == -1) { + if (errno != E2BIG) { + errno_msg("Can't get list of active sessions"); + goto out; + } + free(sidbuf); + nsessions = nret; + sidbuf = (dm_sessid_t *)malloc(nsessions * sizeof(dm_sessid_t)); + if (sidbuf == NULL) { + err_msg("Can't alloc mem to shut down session"); + goto out; + } + error = dm_getall_sessions(nsessions, sidbuf, &nret); + if (error == -1) { + errno_msg("Can't get list of active sessions"); + goto out; + } + } + + /* + * Now we have all the active sessions in our system. + * Query each one until we find ourselves. + */ + sid = sidbuf; + buflen = DM_SESSION_INFO_LEN; + infobuf = malloc(buflen); + if (infobuf == NULL) { + err_msg("Can't alloc memory for session info buffer"); + goto out; + } + + /* + * When we registered our session, we just hammered the last component + * of the path name, so that's all we look for here. This prevents + * mismatches when running at ./migin or some other such foo + */ + cp = strrchr(Progname, '/'); + if (cp) + cp++; + else + cp = Progname; + + + found = 0; + for (i=0; i +#include +#include + +#include +#include +#include +#include + +#include + +extern char *optarg; +extern int optind, optopt, opterr; +char *Progname; +int Verbose; + +int mig_files(dm_sessid_t, char *); +int mk_nonrez(dm_sessid_t, void *, size_t, dm_token_t, dm_off_t); +int set_mrgns(dm_sessid_t, void *, size_t, dm_token_t, dm_off_t, + dm_off_t *); +void clear_mrgns(dm_sessid_t, void *, dm_size_t, dm_token_t); +int lock_file(dm_sessid_t, void *, size_t, dm_right_t, dm_token_t *); +void unlock_file(dm_sessid_t, dm_token_t); +int get_dmchange(dm_sessid_t, void *, size_t, dm_token_t, u_int *); +int create_stgfile(char *, void *, size_t, char *, int *); +int setup_dmapi(dm_sessid_t *); +int save_filedata(dm_sessid_t, void *, size_t, int, dm_size_t); +int extract_fields(char *, char *, size_t *, dm_size_t *); +int save_dataloc(dm_sessid_t, void *, size_t, dm_token_t, char *); + +void usage(char *); + +void +usage( + char *prog) +{ + fprintf(stderr, "Usage: %s ", prog); + fprintf(stderr, " <-v verbose> "); + fprintf(stderr, "\n"); +} + + +int +main( + int argc, + char *argv[]) +{ + + int c; + int error; + char *stage_dir; + dm_sessid_t sid; + + + error = 0; + Progname = argv[0]; + stage_dir = NULL; + + while ((c = getopt(argc, argv, "v")) != EOF) { + switch (c) { + case 'v': + Verbose++; + break; + + case '?': + default: + usage(Progname); + exit(1); + } + } + if (optind >= argc) { + usage(Progname); + exit(1); + } + stage_dir = argv[optind]; + if (stage_dir == NULL) { + usage(Progname); + exit(1); + } + + /* + * Init the dmapi, and get a session. + */ + error = setup_dmapi(&sid); + if (error) + exit(1); + + /* + * Migrate all the files given to us via stdin + */ + error = mig_files(sid, stage_dir); + + + if (dm_destroy_session(sid)) + errno_msg("Can't shut down session, line=%d, errno=%d", __LINE__, errno); + + return(error); +} + +/* + * Migrate all the files given in stdin + */ + +int +mig_files( + dm_sessid_t sid, + char *stage_dir) +{ + void *hanp; + size_t hlen; + dm_size_t fsize; + int error; + u_int change_start, change_end; + int stg_fd; /* staging file descriptor */ + dm_off_t off; /* starting offset */ + dm_token_t token; /* file token */ + char ibuf[IBUFSIZE]; + char handle_buf[HANDLE_LEN]; + char stgpath[MAXPATHLEN]; + + /* + * Read all the lines in std input and migrate each file. + * This simple-minded migout does no batching, sorting, or + * anything else that a real HSM might do. + */ + while (fgets(ibuf, IBUFSIZE, stdin) != NULL) { + error = extract_fields(ibuf, handle_buf, &hlen, &fsize); + if (error) { + err_msg("%s/%d: mangled input line, '%s' ", __FILE__, __LINE__, ibuf); + continue; + } + hanp = (void *)handle_buf; + if (Verbose) { + print_handle(hanp, hlen); + } + + /* + * Create and open the file in the staging directory. + */ + error = create_stgfile(stage_dir, hanp, hlen, stgpath, &stg_fd); + if (error) + continue; + + /* + * Get the file's DMAPI change indicator so that we + * can tell if it changed (either via a data mod, or + * a DM attribute update) while we are staging it out + */ + error = get_dmchange(sid, hanp, hlen, DM_NO_TOKEN, + &change_start); + if (error) { + close(stg_fd); + continue; + } + + /* + * Write all the file's data to our file in the + * staging directory. In a real HSM, the data would + * be copied off to tertiary storage somewhere. + * + * The staging file descriptor will be closed for us + * in all cases. + */ + error = save_filedata(sid, hanp, hlen, stg_fd, fsize); + if (error) + continue; + + + /* + * Get exclusive access to the file so we can blow + * away its data + */ + error = lock_file(sid, hanp, hlen, DM_RIGHT_EXCL, &token); + if (error) { + err_msg("Can't get exclusive access to file, ignoring"); + continue; + } + + /* + * Make sure the file did not change + */ + error = get_dmchange(sid, hanp, hlen, token, &change_end); + if (error) { + unlock_file(sid, token); + continue; + } + if (change_start != change_end) { + unlock_file(sid, token); + err_msg("File changed during stageout, ignoring"); + continue; + } + + /* + * Save the location of the data (the staging file) + * in a private DM attribute so that we can get the + * file back in the future + */ + error = save_dataloc(sid, hanp, hlen, token, stgpath); + if (error) { + err_msg("Can't save location of file data"); + unlock_file(sid, token); + continue; + } + + + /* + * Set up the managed regions on the file so that + * a foray past the fencepost will cause an event to + * be generated. + */ + error = set_mrgns(sid, hanp, hlen, token, fsize, &off); + if (error) { + unlock_file(sid, token); + err_msg("Can't set managed regions"); + continue; + } + + /* + * Now we can safely blow away the data. + */ + error = mk_nonrez(sid, hanp, hlen, token, off); + if (error) { + clear_mrgns(sid, hanp, hlen, token); + } + + /* + * Unlock the file, which releases the token + */ + unlock_file(sid, token); + + } + + return(0); +} + + +/* + * Remove the data for a file + */ +int +mk_nonrez( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_off_t off) +{ + int error; + + error = dm_punch_hole(sid, hanp, hlen, token, off, 0); + if (error == -1) { + errno_msg("Can't punch hole in file, line=%d, errno=%d", __LINE__, errno); + return(1); + } + return(0); +} + + +/* + * Set up the managed regions on a file. We try to leave some of the + * file resident; the actual amount left on-disk is dependent + * on the rounding enforced by the DMAPI implementation. + */ +int +set_mrgns( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_off_t fsize, + dm_off_t *start_off) +{ + dm_off_t rroff; + dm_size_t rlenp; + dm_region_t rgn; + u_int exact_flag; + int error; + + if (fsize > FENCEPOST_SIZE) { + error = dm_probe_hole(sid, hanp, hlen, token, FENCEPOST_SIZE, 0, + &rroff, &rlenp); + if (error == -1) { + errno_msg("Can't probe hole in file, line=%d, errno=%d", __LINE__, errno); + return(1); + } + } else { + rroff = 0; + } + *start_off = rroff; + + /* + * Now we know what the DMAPI and filesystem will support with + * respect to rounding of holes. We try to set our managed region + * to begin at this offset and continue to the end of the file. + * We set the event mask so that we'll trap on all events that + * occur in the managed region. + * + * Note that some implementations may not be able to support + * a managed region that starts someplace other than the beginning + * of the file. If we really cared, we could check the exact_flag. + */ + rgn.rg_offset = rroff; + rgn.rg_size = 0; + rgn.rg_flags = DM_REGION_READ | DM_REGION_WRITE | DM_REGION_TRUNCATE; + error = dm_set_region(sid, hanp, hlen, token, 1, &rgn, &exact_flag); + if (error == -1) { + errno_msg("Can't set managed region, line=%d, errno=%d", __LINE__, errno); + return(1); + } + return(0); +} + + +/* + * Clear a managed region on a file + */ +void +clear_mrgns( + dm_sessid_t sid, + void *hanp, + dm_size_t hlen, + dm_token_t token) +{ + dm_region_t rgn; + u_int exact_flag; + int error; + + rgn.rg_offset = 0; + rgn.rg_size = 0; + rgn.rg_flags = DM_REGION_NOEVENT; + error = dm_set_region(sid, hanp, hlen, token, 1, &rgn, &exact_flag); + if (error) + errno_msg("Can't clear managed regions from file, line=%d, errno=%d", __LINE__, errno); + + return; +} + + +/* + * File rights are accessed via a token. The token must be associated + * with a synchronous event message. So, to obtain either shared or + * exclusive rights to a file, we first associate a token with a message, + * and then request our desired right + */ +int +lock_file( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_right_t right, + dm_token_t *token) +{ + int error; + + error = dm_create_userevent(sid, (size_t)0, (void *)0, token); + if (error == -1) { + errno_msg("Can't create user event for token context, line=%d, errno=%d", __LINE__, errno); + return(1); + } + error = dm_request_right(sid, hanp, hlen, *token, DM_RR_WAIT, right); + if (error == -1) { + errno_msg("Can't get requested right for token, line=%d, errno=%d", __LINE__, errno); + return(1); + } + return(0); +} + + +/* + * Release the lock on a file + */ +void +unlock_file( + dm_sessid_t sid, + dm_token_t token) +{ + int error; + + error = dm_respond_event(sid, token, DM_RESP_CONTINUE, 0, 0, 0); + if (error == -1) + errno_msg("Can't respond to event and release token, line=%d, errno=%d", __LINE__, errno); + + return; +} + + +int +create_stgfile( + char *stage_dir, + void *hanp, + size_t hlen, + char *path, + int *stg_fd) +{ + char handle_str[HANDLE_STR]; + + if (hlen > HANDLE_LEN) { + err_msg("Handle length (%d) too long for file", hlen); + return(1); + } + + strcpy(path, stage_dir); + strcat(path, "/"); + hantoa(hanp, hlen, handle_str); + + /* + * Concat the ascii representation of the file handle + * (which is two times longer than the binary version) + * onto the staging path name + */ + strncat(path, (char *)handle_str, hlen*2); + + if ( (*stg_fd = open(path, O_RDWR | O_CREAT, 0644)) < 0) { + errno_msg("Can't open file %s, line=%d, errno=%d\n", path, __LINE__, errno); + return(1); + } + + return(0); +} + + +/* + * Extract the three fields from the input line. THe input is of + * the form + * filehandle length filehandle file size + * + * The length of the file handle is expected to be less than 64 bytes. + */ +int +extract_fields( + char *ibuf, + char *handle_buf, + size_t *hlen, + dm_size_t *fsize) +{ + char *cp, *start; + size_t len; + char *hanp; + + /* + * Skip any leading white space, and check the length + * of the file handle + */ + cp = ibuf; + while (!isalnum(*cp)) + cp++; + +if( cp != ibuf ) +printf("%s/%d: found leading whitspace to skip\n", __FILE__, __LINE__); + + start = cp; + while (isalnum(*cp)) + cp++; + *cp = '\0'; + +printf("%s/%d: start=(%s)\n", __FILE__, __LINE__, start); + + len = strtol(start, 0, 0); + if (len > HANDLE_LEN) { + err_msg("%s/%d: Handle length %d too long in input line", __FILE__, __LINE__, len); + return(1); + } + +printf("%s/%d: len=%ld\n", __FILE__, __LINE__, len); + + *hlen = len; + + /* + * Skip over white space, and extract the file handle + */ + while (!isalnum(*cp)) + cp++; + hanp = cp; + + /* + * Skip over the ascii length of the file handle, and + * then extract the file's length + */ + cp += len*2; + *cp = '\0'; + +printf("%s/%d: handle buf is (%s)\n", __FILE__, __LINE__, hanp ); + + atohan( hanp, (void**)&handle_buf, &len ); + +printf("%s/%d: len now=%ld\n", __FILE__, __LINE__, len); + + + /* skip over white space */ + while (!isalnum(*cp)) + cp++; + + /* read file length */ + start = cp; + while (isalnum(*cp)) + cp++; + *cp = '\0'; + +printf("%s/%d: file len=%s\n", __FILE__, __LINE__, start); + + *fsize = strtol(start, 0, 0); + +printf("%s/%d: fsize=%ld\n", __FILE__, __LINE__, *fsize); + return(0); + +} + + +/* + * Save the location of the file's data so that we can find + * it again when we're staging the file back in. Rather than store + * the full pathname of the staging file, we just store the handle. + * This means the staging dir must be on a filesystem that supports + * the DMAPI. + */ +int +save_dataloc( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + char *stgpath) +{ + void *stg_hanp; + size_t stg_hlen; + int error; + dm_attrname_t hanp_attrname; + dm_attrname_t hlen_attrname; + + if (dm_path_to_handle(stgpath, &stg_hanp, &stg_hlen) == -1) { + errno_msg("Can't get handle for path %s, line=%d, errno=%d", stgpath, __LINE__, errno); + return(1); + } + + /* + * Since handles are in two parts, they become two attributes. + * This can be useful, since we can extract the length + * separately when we stage the file back in + */ + memcpy((void *)&hanp_attrname.an_chars[0], DLOC_HAN, DM_ATTR_NAME_SIZE); + error = dm_set_dmattr(sid, hanp, hlen, token, &hanp_attrname, + 0, stg_hlen, stg_hanp); + if (error == -1) { + errno_msg("Can't set DM attr of staging filehandle, line=%d, errno=%d",__LINE__, errno); + return(1); + } + + memcpy((void *)&hlen_attrname.an_chars[0], DLOC_HANLEN, DM_ATTR_NAME_SIZE); + error = dm_set_dmattr(sid, hanp, hlen, token, &hlen_attrname, + 0, sizeof(stg_hlen), (void *)&stg_hlen); + if (error == -1) { + errno_msg("Can't set DM attr of staging filehandle length, line=%d, errno=%d", __LINE__, errno); + return(1); + } + return(0); +} diff --git a/dmapi/src/sample_hsm/mls.c b/dmapi/src/sample_hsm/mls.c new file mode 100644 index 000000000..838793b23 --- /dev/null +++ b/dmapi/src/sample_hsm/mls.c @@ -0,0 +1,331 @@ +/* + * Simple util to print out DMAPI info about a file + * + * This code was written by Peter Lawthers, and placed in the public + * domain for use by DMAPI implementors and app writers. + * + * Standard disclaimer: + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define MAX_RGNS 8 /* Arbitrary for this release */ +#define NUM_EXTENTS 4 + +extern char *optarg; +extern int optind, optopt, opterr; +char *Progname; + +void usage(char *); +int mr_info(dm_sessid_t, void *, size_t); +int alloc_info(dm_sessid_t, void *, size_t); +int event_info(dm_sessid_t, void *, size_t); +int handle_info(dm_sessid_t, void *, size_t); + +extern int setup_dmapi(dm_sessid_t *); +extern void errno_msg(char *, ...); +extern void print_handle(void *, size_t); + + +void +usage( + char *prog) +{ + fprintf(stderr, "Usage: %s filename \n ", prog); + fprintf(stderr, "\t-m managed region info\n"); + fprintf(stderr, "\t-a allocation info\n"); + fprintf(stderr, "\t-e event info\n"); + fprintf(stderr, "\t-h handle\n"); +} + + +int +main( + int argc, + char *argv[]) +{ + int c; + int error; + int mr_flag, alloc_flag, handle_flag, event_flag; + void *hanp; + size_t hlen; + char *filename; + dm_sessid_t sid; + + + Progname = argv[0]; + mr_flag = alloc_flag = handle_flag = event_flag = 0; + + while ((c = getopt(argc, argv, "maeh")) != EOF) { + switch (c) { + case 'm': + mr_flag = 1; + break; + case 'a': + alloc_flag = 1; + break; + case 'e': + event_flag = 1; + break; + case 'h': + handle_flag = 1; + break; + case '?': + default: + usage(Progname); + exit(1); + } + } + if (optind >= argc) { + usage(Progname); + exit(1); + } + filename = argv[optind]; + if (filename == NULL) { + usage(Progname); + exit(1); + } + + + /* + * Set up our link to the DMAPI, and get a handle for + * the file we want to query + */ + error = setup_dmapi(&sid); + if (error) + exit(1); + + if (dm_path_to_handle(filename, &hanp, &hlen) == -1) { + printf("Can't get handle for path %s", filename); + error = 1; + goto out; + } + + printf("File %s:\n", filename); + if (mr_flag) { + error = mr_info(sid, hanp, hlen); + if (error) { + error = 1; + goto out; + } + } + if (alloc_flag) { + error = alloc_info(sid, hanp, hlen); + if (error) { + error = 1; + goto out; + } + } + if (event_flag) { + error = event_info(sid, hanp, hlen); + if (error) { + error = 1; + goto out; + } + } + if (handle_flag) { + error = handle_info(sid, hanp, hlen); + if (error) { + error = 1; + goto out; + } + } + +out: + if (dm_destroy_session(sid)) { + errno_msg("Can't shut down session"); + error = 1; + } + + return(error); +} + +/* + * Get the complete list of all managed regions for a file. For now, + * we know that most implementations only support a small number of + * regions, so we don't handle the E2BIG error here. + */ +int +mr_info( + dm_sessid_t sid, + void *hanp, + size_t hlen) +{ + u_int i; + u_int ret; + dm_region_t rgn[MAX_RGNS]; + + memset((char *)&rgn, 0, (sizeof(dm_region_t) * MAX_RGNS)); + if (dm_get_region(sid, hanp, hlen, DM_NO_TOKEN, MAX_RGNS, rgn, &ret)) { + errno_msg("Can't get list of managed regions"); + return(1); + } + printf("\n"); + for (i=0; i +#include +#include +#include + +#include + +extern char *optarg; +extern int optind, opterr, optopt; +extern int errno; + +int Verbose; +char *Progname; + +extern void err_msg(char *, ...); +extern void errno_msg(char *, ...); + +int get_sessions(dm_sessid_t **, u_int *); +int get_tokens(dm_sessid_t, dm_token_t **, u_int *); +void print_session(dm_sessid_t); +void print_tokens(dm_sessid_t); +void kill_session(dm_sessid_t); + +void +usage(char *s) +{ + fprintf(stderr, "Usage: %s \n", s); + fprintf(stderr, "\t-t list tokens\n"); + fprintf(stderr, "\t-l list sessions\n"); + fprintf(stderr, "\t-k kill sessions\n"); + fprintf(stderr, "\t-s \n"); + fprintf(stderr, "\t-v verbose (for kill)\n"); +} + +int +main( + int argc, + char *argv[]) +{ + int c; + int error; + u_int i, nsids; + int list_flag, kill_flag, token_flag, sid_flag; + dm_sessid_t *sidbuf, *sidp, onesid; + char *cp; + + + Progname = argv[0]; + list_flag = sid_flag = kill_flag = token_flag = 0; + + while ((c = getopt(argc, argv, "vlkts:")) != EOF) { + switch (c) { + case 'l': + list_flag = 1; + break; + case 'k': + kill_flag = 1; + break; + case 't': + token_flag = 1; + break; + case 's': + if (sscanf(optarg, "%d", &onesid) <=0 ) { + err_msg("Can't convert sid %s", optarg); + exit(2); + } + sid_flag = 1; + break; + case 'v': + Verbose = 1; + break; + case '?': + default: + usage(Progname); + exit(1); + } + } + if (!list_flag && !sid_flag && !kill_flag && !token_flag) { + usage(Progname); + exit(1); + } + + if (dm_init_service(&cp) == -1) { + err_msg("Can't init dmapi"); + return(1); + } + if (strcmp(cp, DM_VER_STR_CONTENTS)) { + err_msg("Compiled for a different version"); + return(1); + } + + + /* + * Get the list of all sessions in the system + */ + error = get_sessions(&sidbuf, &nsids); + if (error) + exit(1); + + /* + * Walk through the list of sessions do what is right + */ + sidp = sidbuf; + for (i=0; i +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern char *optarg; +extern int optind, optopt, opterr; +extern int errno; +char *Progname; +int Verbose; + +extern int restore_filedata(dm_sessid_t, void *, size_t, dm_token_t, + void *, size_t, dm_off_t); +extern int get_dmchange(dm_sessid_t, void *, size_t, dm_token_t, u_int *); +extern int setup_dmapi(dm_sessid_t *); +extern void err_msg(char *, ...); +extern void errno_msg(char *, ...); + +int stagein_file(dm_sessid_t, dm_token_t, dm_eventmsg_t *); +int inval_file(dm_sessid_t, dm_token_t, dm_eventmsg_t *); +int check_lockstate(dm_sessid_t, void *, size_t, dm_token_t); +int clear_mrgns(dm_sessid_t, void *, size_t, dm_token_t); +int find_msg(dm_sessid_t, dm_token_t, dm_eventmsg_t **); +int get_stghandle(dm_sessid_t, void *, size_t, dm_token_t, void **, + size_t *); +void usage(char *); + + + +void +usage( + char *prog) +{ + fprintf(stderr, "Usage: %s ", prog); + fprintf(stderr, " <-i invalidate file> "); + fprintf(stderr, " <-r restore file> "); + fprintf(stderr, "[-s sid] [-t token] \n"); +} + + +int +main( + int argc, + char *argv[]) +{ + + dm_eventmsg_t *msgheader; + char *sid_str, *token_str; + dm_sessid_t sid; + dm_token_t token; + int c; + int error; + int restore_flag, inval_flag; + char *cp; + + Progname = argv[0]; + sid_str = NULL; + token_str = NULL; + restore_flag = 0; + inval_flag = 0; + + while ((c = getopt(argc, argv, "s:t:ri")) != EOF) { + switch (c) { + case 'r': + restore_flag++; + break; + + case 'i': + inval_flag++; + break; + + case 's': + sid_str = optarg; + break; + + case 't': + token_str = optarg; + break; + + case '?': + default: + usage(Progname); + exit(1); + } + } + if (optind < argc) { + usage(Progname); + exit(1); + } + if (sid_str == NULL || token_str == NULL) { + usage(Progname); + exit(1); + } + if ((restore_flag > 0) && (inval_flag > 0)) { + usage(Progname); + exit(1); + } + + if (sscanf(sid_str, "%d", &sid) <= 0) { + err_msg("Can't convert sid"); + exit(1); + } + if (sscanf(token_str, "%d", &token) <= 0) { + err_msg("Can't convert token"); + exit(1); + } + + /* + * Now we have our session and token. We just need to + * let the DMAPI know we exist so we can use the interface. + * We don't need to create a session since we'll be using + * the session of our parent. + */ + error = dm_init_service(&cp); + if (error == -1) { + errno_msg("Can't init DMAPI"); + exit(1); + } + if (strcmp(cp, DM_VER_STR_CONTENTS)) { + err_msg("Compiled for a different version"); + exit(1); + } + + /* + * Find the message our caller wants us to handle + */ + error = find_msg(sid, token, &msgheader); + if (error) + exit(1); + + /* + * Now service the particular event type + */ + if (restore_flag) + error = stagein_file(sid, token, msgheader); + else + error = inval_file(sid, token, msgheader); + + return(error); +} + + +/* + * Find the data event message that correponds to the token. + * + * RETURNS: + * A pointer to malloc'd memory that contains the message + * we're supposed to handle in the 'msgheader' param. + */ +int +find_msg( + dm_sessid_t sid, + dm_token_t token, + dm_eventmsg_t **msgheader) +{ + void *buf; + size_t buflen, rlen; + int error; + + /* + * Malloc a buffer that we think is large enough for + * the common message header and the event specific part. + * If it's not large enough, we can always resize it. + */ + buflen = sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + HANDLE_LEN; + buf = (void *)malloc(buflen); + if (buf == NULL) { + err_msg("Can't alloc memory for event buffer"); + return(1); + } + + error = dm_find_eventmsg(sid, token, buflen, buf, &rlen); + if (error == -1) { + if (errno != E2BIG) { + free(buf); + errno_msg("Can't obtain message from token"); + return(1); + } + free(buf); + buflen = rlen; + buf = (void *)malloc(buflen); + if (buf == NULL) { + err_msg("Can't resize event buffer"); + return(1); + } + error = dm_find_eventmsg(sid, token, buflen, buf, &rlen); + if (error == -1) { + errno_msg("Can't get message with resized buffer"); + return(1); + } + } + + *msgheader = (dm_eventmsg_t *)buf; + return(0); +} + + +/* + * Check the lock state associated with the file. If the token + * does not reference exclusive access, try to upgrade our lock. + * If we can't upgrade, drop the lock and start over + */ +int +check_lockstate( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token) +{ + int error; + dm_right_t right; + u_int change_start, change_end; + + error = dm_query_right(sid, hanp, hlen, token, &right); + if (error == -1) { + errno_msg("Can't query file access rights"); + return(1); + } +#ifdef __sgi + /* + * There are no access rights on the SGI. 1 means it's + * there. + */ + if (right == DM_RIGHT_SHARED) + return 0; +#endif + + if (right != DM_RIGHT_EXCL) { + error = dm_request_right(sid, hanp, hlen, token, 0, + DM_RIGHT_EXCL); + if (error == -1) { + if (errno != EAGAIN) { + errno_msg("Can't upgrade lock"); + return(1); + } + error = get_dmchange(sid, hanp, hlen, token, + &change_start); + if (error) + return(1); + + + error = dm_release_right(sid, hanp, hlen, token); + if (error == -1) { + errno_msg("Can't release file access rights"); + return(1); + } + error = dm_request_right(sid, hanp, hlen, token, + DM_RR_WAIT, DM_RIGHT_EXCL); + if (error == -1) { + errno_msg("Can't get exclusive right to file"); + return(1); + } + + /* + * If the file changed while we slept, then someone + * must have modified the file + */ + error = get_dmchange(sid, hanp, hlen, token, + &change_end); + if (error == -1) + return(1); + + if (change_start != change_end) { + err_msg("File changed while waiting for lock"); + return(1); + } + } + } + return(0); +} + + +/* + * Stage in the data for a file + */ +int +stagein_file( + dm_sessid_t sid, + dm_token_t token, + dm_eventmsg_t *msgheader) +{ + + void *stg_hanp, *hanp; + size_t stg_hlen, hlen; + int error, ret_errno; + dm_response_t reply; + dm_data_event_t *msg; + + /* + * Extract the event-specific info from the message header, + * then get the file handle. + */ + msg = DM_GET_VALUE(msgheader, ev_data, dm_data_event_t *); + hanp = DM_GET_VALUE(msg, de_handle, void *); + hlen = DM_GET_LEN(msg, de_handle); + + /* + * Check our permissions. We need exclusive access to the + * file to stage it back in. + */ + error = check_lockstate(sid, hanp, hlen, token); + if (error) + goto out; + + /* + * get the staging file handle from it's DM attributes + */ + stg_hanp = NULL; + error = get_stghandle(sid, hanp, hlen, token, &stg_hanp, &stg_hlen); + if (error) + goto out; + + /* + * We keep the exclusive lock held for the *entire* duration + * of the stagein. This is not required, but just quick and + * [sl]easy. For a large file, it is typically better to release + * the lock, and have a sliding window of managed regions to allow + * people to consume the data as it is being read in. + */ + error = restore_filedata(sid, hanp, hlen, token, stg_hanp, stg_hlen, + msg->de_offset); + if (error) + goto out; + + /* + * Now that the data is restored, and while we still have exclusive + * access to the file, clear the managed regions. + */ + error = clear_mrgns(sid, hanp, hlen, token); + if (error) + goto out; + +out: + if (stg_hanp) + free((char *)stg_hanp); + + /* + * Figure out what our response to the event will be. Once + * we've responded to the event, the token is no longer valid. + * On error, we pick the (less than helpful) errno EIO to signal + * to the user that something went wrong. + */ + if (error) { + reply = DM_RESP_ABORT; + ret_errno = EIO; + } else { + reply = DM_RESP_CONTINUE; + ret_errno = 0; + } + (void)dm_respond_event(sid, token, reply, ret_errno, 0, 0); + + return(ret_errno); + +} + +/* + * Turn off event monitoring for a file. In a real HSM, we would + * probably want to either invalidate the file's data on + * tertiary storage, or start some aging process so that it will + * eventually go away. + * + * The assumption is that for write and truncate events, the file + * data is about to be invalidated. + */ +int +inval_file( + dm_sessid_t sid, + dm_token_t token, + dm_eventmsg_t *msgheader) +{ + dm_data_event_t *msg; + void *hanp; + size_t hlen; + int error, ret_errno; + dm_response_t reply; + + /* + * Extract the event-specific info from the message header, + * then get the file handle. + */ + msg = DM_GET_VALUE(msgheader, ev_data, dm_data_event_t *); + hanp = DM_GET_VALUE(msg, de_handle, void *); + hlen = DM_GET_LEN(msg, de_handle); + + /* + * Check our permissions. We need exclusive access to the + * file to clear our managed regions. + */ + error = check_lockstate(sid, hanp, hlen, token); + if (error) + goto out; + + /* + * Clear all the managed regions for the file. + */ + error = clear_mrgns(sid, hanp, hlen, token); + +out: + /* + * Figure out what our response to the event will be. Once + * we've responded to the event, the token is no longer valid. + * On error, we pick the (less than helpful) errno EIO to signal + * to the user that something went wrong. + */ + if (error) { + reply = DM_RESP_ABORT; + ret_errno = EIO; + } else { + reply = DM_RESP_CONTINUE; + ret_errno = 0; + } + (void)dm_respond_event(sid, token, reply, ret_errno, 0, 0); + + return(ret_errno); +} + +/* + * Clear all of the managed regions for a file. + */ +int +clear_mrgns( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token) +{ + dm_region_t *rgn; + u_int nregions, nret; + u_int exact_flag; + int i; + int error, retval; + + /* + * We take a guess first and assume there is only one managed + * region per file. There should'nt be more than this, but + * it never hurts to check, since we want to make sure that + * all regions are turned off. + * + * The main purpose of this is to demonstrate the use of the + * E2BIG paradigm. + */ + retval = 1; + nregions = 1; + rgn = (dm_region_t *)malloc(nregions * sizeof(dm_region_t)); + if (rgn == NULL) { + err_msg("Can't allocate memory for region buffers"); + goto out; + } + + error = dm_get_region(sid, hanp, hlen, token, nregions, rgn, &nret); + if (error == -1) { + if (errno != E2BIG) { + errno_msg("Can't get list of managed regions for file"); + goto out; + } + + /* + * Now we know how many managed regions there are, so we can + * resize our buffer + */ + nregions = nret; + free(rgn); + rgn = (dm_region_t *)malloc(nregions * sizeof(dm_region_t)); + if (rgn == NULL) { + err_msg("Can't resize region buffers"); + goto out; + } + error = dm_get_region(sid, hanp, hlen, token, nregions, rgn, + &nret); + if (error == -1) { + errno_msg("Can't get list of managed regions for file"); + goto out; + } + } + + /* + * Clear all the managed regions + */ + for (i=0; irg_offset = 0; + rgn->rg_size = 0; + rgn->rg_flags = DM_REGION_NOEVENT; + rgn++; + } + error = dm_set_region(sid, hanp, hlen, token, nregions, rgn, + &exact_flag); + if (error == -1) { + errno_msg("Can't clear list of managed regions for file"); + } + retval = 0; + +out: + if (rgn != NULL) + free(rgn); + + return(retval); +} + + +/* + * Extract the staging file handle from a file's DM attributes + */ +int +get_stghandle( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + void **stg_hanp, + size_t *stg_hlen) +{ + void *han_buf; + size_t han_len; + int error; + size_t rlen; + dm_attrname_t hanp_attrname; + dm_attrname_t hlen_attrname; + + /* + * First get the length of the file handle, so we + * can size our buffer correctly + */ + memcpy((void *)&hlen_attrname.an_chars[0], DLOC_HANLEN, DM_ATTR_NAME_SIZE); + error = dm_get_dmattr(sid, hanp, hlen, token, &hlen_attrname, + sizeof(size_t), &han_len, &rlen); + if (error == -1) { + /* + * On any error, even E2BIG, we bail since the size of + * the file handle should be a constant + */ + errno_msg("Can't get size of staging file handle"); + return(1); + } + if (rlen != sizeof(size_t)) { + err_msg("File handle length component incorrect"); + return(1); + } + + /* + * Malloc space for our staging file handle, and + * extract it from our DM attributes + */ + han_buf = (void *)malloc(han_len); + if (han_buf == NULL) { + err_msg("Can't alloc memory for file handle"); + return(1); + } + + memcpy((void *)&hanp_attrname.an_chars[0], DLOC_HAN, DM_ATTR_NAME_SIZE); + error = dm_get_dmattr(sid, hanp, hlen, token, &hanp_attrname, + han_len, han_buf, &rlen); + if (error == -1) { + errno_msg("Can't get staging file handle"); + free(han_buf); + return(1); + } + if (rlen != han_len) { + err_msg("File handle is incorrect length"); + free(han_buf); + return(1); + } + *stg_hanp = han_buf; + *stg_hlen = han_len; + return(0); +} + diff --git a/dmapi/src/simple/dm_create_session.c b/dmapi/src/simple/dm_create_session.c new file mode 100644 index 000000000..a30165bf8 --- /dev/null +++ b/dmapi/src/simple/dm_create_session.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +#include +#include +#include +#include + +main( int argc, char **argv ) +{ + extern char *optarg; + extern int optind; + int c; + int ret; + dm_sessid_t oldsid = DM_NO_SESSION; + dm_sessid_t newsid = 0; + char *sessinfo = "test1"; + char *versionstr; + + while( (c = getopt(argc, argv, "hs:i:")) != -1 ) { + switch(c){ + case 's': + oldsid = atoi( optarg ); + break; + case 'i': + sessinfo = optarg; + break; + case 'h': + fprintf(stderr, "Usage: %s [-s oldsid] [-i sessinfo_txt]\n", argv[0]); + exit(2); + } + } + + if( dm_init_service( &versionstr ) < 0 ) + exit(1); + + ret = dm_create_session( oldsid, sessinfo, &newsid); + printf( "ret=%d\n", ret ); + printf( "newsid=%d\n", newsid ); + +} + diff --git a/dmapi/src/simple/dm_destroy_session.c b/dmapi/src/simple/dm_destroy_session.c new file mode 100644 index 000000000..68ed8c571 --- /dev/null +++ b/dmapi/src/simple/dm_destroy_session.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +#include +#include +#include +#include + +main( int argc, char **argv ) +{ + extern char *optarg; + extern int optind; + int c; + int ret; + dm_sessid_t sid = 0; + char *versionstr; + + while( (c = getopt(argc, argv, "hs:")) != -1 ) { + switch(c){ + case 's': + sid = atoi( optarg ); + break; + case 'h': + fprintf(stderr, "Usage: %s <-s sid>\n", argv[0] ); + exit(2); + } + } + + if( sid == 0 ){ + fprintf(stderr, "%s: must specify -s\n", argv[0] ); + exit(1); + } + + if( dm_init_service( &versionstr ) < 0 ) + exit(1); + + ret = dm_destroy_session( sid ); + printf( "ret=%d\n", ret ); +} diff --git a/dmapi/src/simple/dm_find_eventmsg.c b/dmapi/src/simple/dm_find_eventmsg.c new file mode 100644 index 000000000..d993879d8 --- /dev/null +++ b/dmapi/src/simple/dm_find_eventmsg.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +#include +#include +#include +#include + +main( int argc, char **argv ) +{ + extern char *optarg; + extern int optind; + int c; + int ret; + dm_sessid_t sid = 0; + dm_token_t token = 0; + dm_eventmsg_t msg; + size_t rlen; + int buflen = sizeof(dm_eventmsg_t) + 100; + char *versionstr; + + while( (c = getopt(argc, argv, "hs:t:l:q")) != -1 ) { + switch(c){ + case 's': + sid = atoi( optarg ); + break; + case 't': + token = atoi( optarg ); + break; + case 'l': + buflen = atoi( optarg ); + break; + case 'q': + printf("dm_eventmsg_t=%d\n", sizeof(dm_eventmsg_t) ); + exit(0); + case 'h': + fprintf(stderr, "Usage: %s <-s sid> <-t token> [-l buflen]\n", argv[0]); + fprintf(stderr, " %s -q\n", argv[0]); + exit(2); + } + } + + if( sid == 0 ){ + fprintf(stderr, "%s: must specify -s\n", argv[0] ); + exit(1); + } + + if( token == 0 ){ + fprintf(stderr, "%s: must specify -t\n", argv[0] ); + exit(1); + } + + if( dm_init_service( &versionstr ) < 0 ) + exit(1); + + ret = dm_find_eventmsg( sid, token, buflen, &msg, &rlen ); + printf( "ret=%d\n", ret ); + printf( "rlen=%d\n", rlen ); +} diff --git a/dmapi/src/simple/dm_getall_sessions.c b/dmapi/src/simple/dm_getall_sessions.c new file mode 100644 index 000000000..622e0b4a5 --- /dev/null +++ b/dmapi/src/simple/dm_getall_sessions.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +#include +#include +#include +#include +#include +#include + +main( int argc, char **argv ) +{ + extern char *optarg; + extern int optind; + int c; + int ret; + dm_sessid_t *sidbuf; + u_int nelem = 100; + u_int rnelem = 0; + int i; + char *versionstr; + int anyway = 0; /* attempt to show this many elements anyway, + * even if it looks like nothing was returned. + */ + + while( (c = getopt(argc, argv, "hn:x:")) != -1 ) { + switch(c){ + case 'n': + nelem = atoi( optarg ); + break; + case 'x': + anyway = atoi( optarg ); + break; + case 'h': + fprintf(stderr, "Usage: %s [-n nelem]\n", argv[0]); + exit(2); + } + } + + if( (sidbuf = malloc( sizeof(*sidbuf) * nelem )) == NULL ){ + fprintf(stderr, "%s: malloc failed\n", argv[0] ); + exit(1); + } + + memset( sidbuf, 0, sizeof(*sidbuf) * nelem ); + + if( dm_init_service( &versionstr ) < 0 ) + exit(1); + + ret = dm_getall_sessions( nelem, sidbuf, &rnelem ); + printf( "ret=%d\n", ret ); + printf( "rnelem=%d\n", rnelem ); + + /* user wants us to try to show a specific number of elements */ + if( anyway > 0 ) + rnelem = anyway; + + printf("sids=\""); + for( i = 0; i < rnelem; i++ ){ + printf("%d ", sidbuf[i]); + } + printf("\"\n"); +} + diff --git a/dmapi/src/simple/dm_getall_tokens.c b/dmapi/src/simple/dm_getall_tokens.c new file mode 100644 index 000000000..87dd301d9 --- /dev/null +++ b/dmapi/src/simple/dm_getall_tokens.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +#include +#include +#include +#include +#include + +main( int argc, char **argv ) +{ + extern char *optarg; + extern int optind; + int c; + int ret; + dm_token_t *tokenbuf; + u_int nelem = 100; + u_int rnelem = 0; + dm_sessid_t sid = 0; + int i; + char *versionstr; + + while( (c = getopt(argc, argv, "hs:n:")) != -1 ) { + switch(c){ + case 's': + sid = atoi( optarg ); + break; + case 'n': + nelem = atoi( optarg ); + break; + case 'h': + fprintf(stderr, "Usage: %s <-s sid> [-n nelem]\n", argv[0]); + exit(2); + } + } + + if( sid == 0 ){ + fprintf(stderr, "%s: must specify -s\n", argv[0] ); + exit(1); + } + + if( (tokenbuf = malloc( sizeof(dm_token_t) * nelem )) == NULL ){ + fprintf(stderr, "%s: malloc failed\n", argv[0] ); + exit(1); + } + + if( dm_init_service( &versionstr ) < 0 ) + exit(1); + + ret = dm_getall_tokens( sid, nelem, tokenbuf, &rnelem ); + printf( "ret=%d\n", ret ); + printf( "rnelem=%d\n", rnelem ); + + printf("tokens=\""); + for( i = 0; i < rnelem; i++ ){ + printf("%d ", tokenbuf+i); + } + printf("\"\n"); +} diff --git a/dmapi/src/simple/dm_query_session.c b/dmapi/src/simple/dm_query_session.c new file mode 100644 index 000000000..3dedb698f --- /dev/null +++ b/dmapi/src/simple/dm_query_session.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +#include +#include +#include +#include + +main( int argc, char **argv ) +{ + extern char *optarg; + extern int optind; + int c; + int ret; + char *sessinfo; + size_t rlen = 0; + dm_sessid_t sid = 0; + int buflen = 100; + char *versionstr; + + while( (c = getopt(argc, argv, "hs:l:")) != -1 ) { + switch(c){ + case 's': + sid = atoi( optarg ); + break; + case 'l': + buflen = atoi( optarg ); + break; + case 'h': + fprintf(stderr, "Usage: %s <-s sid> [-l buflen]\n", argv[0]); + exit(2); + } + } + + if( sid == 0 ){ + fprintf(stderr, "%s: must specify -s\n", argv[0] ); + exit(1); + } + + if( (sessinfo = malloc( sizeof(char*) * buflen )) == NULL ){ + fprintf(stderr, "%s: malloc failed\n", argv[0] ); + exit(1); + } + + if( dm_init_service( &versionstr ) < 0 ) + exit(1); + + ret = dm_query_session( sid, buflen, sessinfo, &rlen ); + printf( "ret=%d\n", ret ); + printf( "rlen=%d\n", rlen ); + if( ret != -1 ) + printf( "sessinfo=%s\n", sessinfo ); +} diff --git a/dmapi/src/suite1/cmd/create_userevent.c b/dmapi/src/suite1/cmd/create_userevent.c new file mode 100644 index 000000000..721378a45 --- /dev/null +++ b/dmapi/src/suite1/cmd/create_userevent.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function create_userevent(). The +command line is: + + create_userevent [-s sid] string + +where string is the msgdata to be stored in the event. +sid is the session ID to use for the event. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-s sid] string\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *string; + dm_token_t token; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "s:")) != EOF) { + switch (opt) { + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + string = argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + if (dm_create_userevent(sid, strlen(string)+ 1, string, &token)) { + fprintf(stderr, "dm_create_userevent failed, %s\n", + strerror(errno)); + exit(1); + } + + fprintf(stdout, "New token %d\n", token); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/dm_handle.c b/dmapi/src/suite1/cmd/dm_handle.c new file mode 100644 index 000000000..b69986f50 --- /dev/null +++ b/dmapi/src/suite1/cmd/dm_handle.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include +#include + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test all the DMAPI functions in dm_handle.c. The +command line is: + + dm_handle pathname + +where pathname is the name of a file. If any function fails, an error message +containing the work ERROR will be written to stderr. + +Tested DMAPI functions are: + dm_fd_to_handle + dm_handle_cmp + dm_handle_free + dm_handle_hash + dm_handle_is_valid + dm_handle_to_fshandle + dm_handle_to_fsid + dm_handle_to_ino + dm_handle_to_igen + dm_make_handle + dm_make_fshandle + dm_path_to_handle + dm_path_to_fshandle + +----------------------------------------------------------------------------*/ + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *pathname; + char *name; + void *hanp1, *hanp2, *hanp3, *fshanp1, *fshanp2, *fshanp3; + size_t hlen1, hlen2, hlen3, fshlen1, fshlen2, fshlen3; + u_int hash1, hash2, hash3, fshash1, fshash2, fshash3; + dm_fsid_t fsid; + dm_ino_t ino; + dm_igen_t igen; + char buffer[100]; + char buffer1[100]; + char fsbuffer1[100]; + char buffer2[100]; + char fsbuffer2[100]; + char buffer3[100]; + char fsbuffer3[100]; + int fd; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + if (argc != 2) { + fprintf(stderr, "usage: %s path\n", argv[0]); + exit(1); + } + pathname = argv[1]; + + (void)dm_init_service(&name); + + if (dm_path_to_handle(pathname, &hanp1, &hlen1) != 0) { + fprintf(stderr, "dm_path_to_handle failed, %s\n", + strerror(errno)); + exit(1); + } + hash1 = dm_handle_hash(hanp1, hlen1); + hantoa(hanp1, hlen1, buffer1); + fprintf(stdout, " han1: hash %u value %s (dm_path_to_handle)\n", + hash1, buffer1); + if (dm_handle_is_valid(hanp1, hlen1) == DM_FALSE) { + fprintf(stderr, "ERROR: han1 is not valid\n"); + } + + if (dm_path_to_fshandle(pathname, &fshanp1, &fshlen1) != 0) { + fprintf(stderr, "dm_path_to_fshandle failed, %s\n", + strerror(errno)); + exit(1); + } + fshash1 = dm_handle_hash(fshanp1, fshlen1); + hantoa(fshanp1, fshlen1, fsbuffer1); + fprintf(stdout, "fshan1: hash %u value %s (dm_path_to_fshandle\n", + fshash1, fsbuffer1); + if (dm_handle_is_valid(fshanp1, fshlen1) == DM_FALSE) { + fprintf(stderr, "ERROR: fshan1 is not valid\n"); + } + + if ((fd = open(pathname, O_RDONLY)) < 0) { + fprintf(stderr, "open of %s failed, %s\n", pathname, + strerror(errno)); + exit(1); + } + if (dm_fd_to_handle(fd, &hanp2, &hlen2) != 0) { + fprintf(stderr, "dm_fd_to_handle failed, %s\n", + strerror(errno)); + exit(1); + } + (void)close(fd); + hash2 = dm_handle_hash(hanp2, hlen2); + hantoa(hanp2, hlen2, buffer2); + fprintf(stdout, " han2: hash %u value %s (dm_fd_to_handle)\n", + hash2, buffer2); + if (dm_handle_is_valid(hanp2, hlen2) == DM_FALSE) { + fprintf(stderr, "ERROR: han2 is not valid\n"); + } + + if (dm_handle_to_fshandle(hanp2, hlen2, &fshanp2, &fshlen2) != 0) { + fprintf(stderr, "dm_handle_to_fshandle failed, %s\n", + strerror(errno)); + exit(1); + } + fshash2 = dm_handle_hash(fshanp2, fshlen2); + hantoa(fshanp2, fshlen2, fsbuffer2); + fprintf(stdout, "fshan2: hash %u value %s (dm_handle_to_fshandle)\n", + fshash2, fsbuffer2); + if (dm_handle_is_valid(fshanp2, fshlen2) == DM_FALSE) { + fprintf(stderr, "ERROR: fshan2 is not valid\n"); + } + + if (dm_handle_cmp(hanp1, hlen1, hanp2, hlen2)) { + fprintf(stderr, "ERROR: han1 and han2 differ in dm_handle_cmp\n"); + } + if (strcmp(buffer1, buffer2)) { + fprintf(stderr, "ERROR: han1 and han2 differ in strcmp\n"); + } + if (hash1 != hash2) { + fprintf(stderr, "ERROR: hash1 and hash2 differ\n"); + } + + if (dm_handle_cmp(fshanp1, fshlen1, fshanp2, fshlen2)) { + fprintf(stderr, "ERROR: fshan1 and fshan2 differ in dm_handle_cmp\n"); + } + if (strcmp(fsbuffer1, fsbuffer2)) { + fprintf(stderr, "ERROR: fshan1 and fshan2 differ in strcmp\n"); + } + if (fshash1 != fshash2) { + fprintf(stderr, "ERROR: fshash1 and fshash2 differ\n"); + } + + /* Break the handle into its component parts and display them. Use + hantoa() instead of printing the parts directly because some are + 32 bits on Veritas and 64 bits on SGI. + */ + + if (dm_handle_to_fsid(hanp1, hlen1, &fsid) != 0) { + fprintf(stderr, "dm_handle_to_fsid failed, %s\n", + strerror(errno)); + exit(1); + } + hantoa(&fsid, sizeof(fsid), buffer); + fprintf(stdout, "fsid %s (dm_handle_to_fsid)\n", buffer); + + if (dm_handle_to_ino(hanp1, hlen1, &ino) != 0) { + fprintf(stderr, "dm_handle_to_ino failed, %s\n", + strerror(errno)); + exit(1); + } + hantoa(&ino, sizeof(ino), buffer); + fprintf(stdout, "ino %s (dm_handle_to_ino)\n", buffer); + + if (dm_handle_to_igen(hanp1, hlen1, &igen) != 0) { + fprintf(stderr, "dm_handle_to_igen failed, %s\n", + strerror(errno)); + exit(1); + } + hantoa(&igen, sizeof(igen), buffer); + fprintf(stdout, "igen %s (dm_handle_to_igen)\n", buffer); + + /* Now use the parts to remake the handle and verify we get the same + answer. + */ + + if (dm_make_handle(&fsid, &ino, &igen, &hanp3, &hlen3) != 0) { + fprintf(stderr, "dm_make_handle failed, %s\n", + strerror(errno)); + exit(1); + } + hash3 = dm_handle_hash(hanp3, hlen3); + hantoa(hanp3, hlen3, buffer3); + fprintf(stdout, " han3: hash %u value %s (dm_make_handle)\n", + hash3, buffer3); + if (dm_handle_is_valid(hanp3, hlen3) == DM_FALSE) { + fprintf(stderr, "ERROR: han3 is not valid\n"); + } + + if (dm_handle_cmp(hanp1, hlen1, hanp3, hlen3)) { + fprintf(stderr, "ERROR: hanp1 and hanp3 differ in dm_handle_cmp\n"); + } + if (strcmp(buffer1, buffer3)) { + fprintf(stderr, "ERROR: hanp1 and hanp3 differ in strcmp\n"); + } + if (hash1 != hash3) { + fprintf(stderr, "ERROR: hash1 and hash3 differ\n"); + } + + if (dm_make_fshandle(&fsid, &fshanp3, &fshlen3) != 0) { + fprintf(stderr, "dm_make_fshandle failed, %s\n", + strerror(errno)); + exit(1); + } + fshash3 = dm_handle_hash(fshanp3, fshlen3); + hantoa(fshanp3, fshlen3, fsbuffer3); + fprintf(stdout, "fshan3: hash %u value %s (dm_make_fshandle)\n", + fshash3, fsbuffer3); + if (dm_handle_is_valid(fshanp3, fshlen3) == DM_FALSE) { + fprintf(stderr, "ERROR: fshan3 is not valid\n"); + } + + if (dm_handle_cmp(fshanp1, fshlen1, fshanp3, fshlen3)) { + fprintf(stderr, "ERROR: fshan1 and fshan3 differ in dm_handle_cmp\n"); + } + if (strcmp(fsbuffer1, fsbuffer3)) { + fprintf(stderr, "ERROR: fshan1 and fshan3 differ in strcmp\n"); + } + if (fshash1 != fshash3) { + fprintf(stderr, "ERROR: fshash1 and fshash3 differ\n"); + } + + dm_handle_free(hanp1, hlen1); + dm_handle_free(hanp2, hlen2); + dm_handle_free(hanp3, hlen3); + dm_handle_free(fshanp1, fshlen1); + dm_handle_free(fshanp2, fshlen2); + dm_handle_free(fshanp3, fshlen3); +} diff --git a/dmapi/src/suite1/cmd/downgrade_right.c b/dmapi/src/suite1/cmd/downgrade_right.c new file mode 100644 index 000000000..fb2ef25c7 --- /dev/null +++ b/dmapi/src/suite1/cmd/downgrade_right.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_downgrade_right(). The +command line is: + + downgrade_right {-F} [-s sid] token {pathname|handle} + +where: +-F + when a pathname is specified, -F indicates that its filesystem handle + should be used rather than its file object handle. +sid + is the dm_sessid_t to use rather than the default test session. +token + is the dm_token_t to use. +{pathname|handle} + is either a handle, or is the pathname of a file whose handle is + to be used. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-F] [-s sid] token {pathname|handle}\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token; + char *object; + void *hanp; + size_t hlen; + int Fflag = 0; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fs:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + token = atol(argv[optind++]); + object = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file or filesystem's handle. */ + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle from %s\n", object); + exit(1); + } + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + if (dm_downgrade_right(sid, hanp, hlen, token)) { + fprintf(stderr, "dm_downgrade_right failed, %s\n", + strerror(errno)); + return(1); + } + + dm_handle_free(hanp, hlen); +} diff --git a/dmapi/src/suite1/cmd/fd_to_handle.c b/dmapi/src/suite1/cmd/fd_to_handle.c new file mode 100644 index 000000000..8b7df4404 --- /dev/null +++ b/dmapi/src/suite1/cmd/fd_to_handle.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +/* Given a file object's pathname, print the object's handle. */ + +#include +#include + +#include +#include +#include +#include + +#include + + +static void +hantoa( + void *hanp, + size_t hlen, + char *handle_str) +{ + u_char *cp= (u_char *)hanp; + int i; + + for (i = 0;i < hlen; i++, handle_str += 2) + sprintf(handle_str, "%.2x", *cp++); + *handle_str = '\0'; +} + +int +main( + int argc, + char **argv) +{ + char *name; + void *hanp; + size_t hlen; + char buffer[100]; + int fd; + + if (argc != 2) { + fprintf(stderr, "usage: %s path\n", argv[0]); + exit(1); + } + + (void)dm_init_service(&name); + + if ((fd = open(argv[1], O_RDONLY)) < 0) { + fprintf(stderr, "open of %s failed, %s\n", argv[1], + strerror(errno)); + exit(1); + } + if (dm_fd_to_handle(fd, &hanp, &hlen) != 0) { + fprintf(stderr, "dm_fd_to_handle failed, %s\n", + strerror(errno)); + exit(1); + } + hantoa(hanp, hlen, buffer); + + fprintf(stdout, "handle %s, path %s\n", buffer, argv[1]); +} diff --git a/dmapi/src/suite1/cmd/get_allocinfo.c b/dmapi/src/suite1/cmd/get_allocinfo.c new file mode 100644 index 000000000..f6f366014 --- /dev/null +++ b/dmapi/src/suite1/cmd/get_allocinfo.c @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include +#include +#include + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_get_allocinfo(). The +command line is: + + get_allocinfo [-D] [-n nelem] [-o offp] [-s sid] pathname + +where pathname is the name of a file, 'offp' is a byte offset from the +beginning of the file where you want to start dumping, and 'nelem' allows +you to specify how many extent structures to use in each dm_get_allocinfo +call. + +The code checks the returned extents as much as possible for errors. +It detects bad ex_type values, verifies that there is always a trailing +hole at the end of the file, that the ex_offset of each extent matches the +ex_offset+ex_length of the previous extent, and that ex_offset+ex_length +is always an even multiple of 512. It verifies that all ex_offset values +after the first fall on a 512-byte boundary. It verifies that the '*offp' +value returned by dm_get_allocinfo() is 0 at the end of the file, and +equals ex_offset+ex_length of the last extent if not at the end of the file. +Any error is reported to stderr, and the program then terminates with a +non-zero exit status. + +The program produces output similar to xfs_bmap in order to make comparison +easier. Here is some sample output. + +f1: offset 1 + rc 0, nelemp 17 + 0: [0..127]: resv [1..511] + +Line 1 gives the name of the file and the byte offset within the file where +the dump started. Line 2 appears once for each dm_get_allocinfo() call, +giving the return value (rc) and the number of extents which were returned. +Line 3 is repeated once for each extent. The first field "0:" is the extent +number. The second field "[0..127]:" give the starting and ending block for +the extent in 512-byte units. The third field is either "resv" to indicate +allocated space or "hole" if the extent is a hole. The fourth field +"[1..511]" only appears if the dump did not start with byte zero of the +first block. In that case, the first number shows the actual byte offset +within the block (1 in this case). The second number should always be +511 since we always dump to the end of a block. + +Possible tests +-------------- + +Dump some holey files and compare the output of this program with xfs_bmap. + +Produce a file with holes, and perform the following tests using just one +extent (-e 1). + Dump extents from beginning of the file. + Dump from byte 1 of the file. + Dump from the last byte of the first extent. + Dump from the first byte of the second extent. + Dump from the middle of the second extent. + Dump the first byte of the last extent. + Dump the last byte of the last extent. + Dump the first byte after the last extent. + Dump starting at an offset way past the end of the file. + +Produce a fragmented file with many adjacent DM_EXTENT_RES extents. + Repeat the above tests. + +Produce a GRIO file with holes. + Repeat the above tests. + +Run the following shell script. + +#!/bin/ksh + +# Dump the same holey file $max times, each time using one less extent +# structure than the previous time. The grep and diff code +# checks to make sure that you get the same answer each time, no matter +# how many extents you use. If all is okay, The only messages you will +# see are the "trial $num" messages. + +max=20 # should be bigger than the number extents in the file + +num=$max +while [ $num -gt 0 ] +do + echo "trial $num" + ./test_alloc -e $num f1 | grep '\[' > x.$num + if [ $num -lt $max ] + then + diff x.$num x.$max + fi + num=`expr $num - 1` +done + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + +static int print_alloc(dm_sessid_t sid, void* hanp, size_t hlen, + char *pathname, dm_off_t startoff, u_int nelem); + +char *Progname; +int Dflag = 0; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-D] [-n nelem] [-o off] [-s sid] " + "pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_off_t startoff = 0; /* starting offset */ + u_int nelem = 100; + char *pathname; + void *hanp; + size_t hlen; + dm_stat_t sbuf; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Dn:o:s:")) != EOF) { + switch(opt) { + case 'D': + Dflag++; + break; + case 'n': + nelem = atol(optarg); + break; + case 'o': + startoff = atoll(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind]; + + if (dm_init_service(&name)) { + fprintf(stderr, "dm_init_service failed, %s\n", + strerror(errno)); + exit(1); + } + + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle and verify that it is a regular file. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for %s\n", pathname); + exit(1); + } + if (dm_get_fileattr(sid, hanp, hlen, DM_NO_TOKEN, DM_AT_STAT, &sbuf)) { + fprintf(stderr, "dm_get_fileattr failed\n"); + exit(1); + } + if (!S_ISREG(sbuf.dt_mode)) { + fprintf(stderr, "%s is not a regular file\n", pathname); + exit(1); + } + + /* Print the allocation. */ + + if (print_alloc(sid, hanp, hlen, pathname, startoff, nelem)) + exit(1); + + dm_handle_free(hanp, hlen); + exit(0); +} + + +static int +print_alloc( + dm_sessid_t sid, + void *hanp, + size_t hlen, + char *pathname, + dm_off_t startoff, + u_int nelem) +{ + dm_off_t endoff; + dm_extent_t *extent; + u_int nelemp; + u_int num = 0; + u_int i; + char *type = NULL; + int rc; + +#ifdef __sgi + fprintf(stdout, "%s: starting offset %lld\n", pathname, startoff); +#else + fprintf(stdout, "%s: starting offset %d\n", pathname, startoff); +#endif + + /* Allocate space for the number of extents requested by the user. */ + + if ((extent = malloc(nelem * sizeof(*extent))) == NULL) { + fprintf(stderr, "can't malloc extent structures\n"); + return(1); + } + + rc = 1; + endoff = startoff; + + while (rc != 0) { + rc = dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, &startoff, + nelem, extent, &nelemp); + + if (rc < 0) { + fprintf(stderr, "dm_get_allocinfo failed, %s\n", + strerror(errno)); + return(1); + } + + fprintf(stdout, "\treturned %d, nelemp %d\n", rc, nelemp); + if (Dflag && nelemp) + fprintf(stdout, " ex_type ex_offset ex_length\n"); + + /* Note: it is possible for nelemp to be zero! */ + + for (i = 0; i < nelemp; i++) { + /* The extent must either be reserved space or a hole. + */ + + switch (extent[i].ex_type) { + case DM_EXTENT_RES: + type = "resv"; + break; + case DM_EXTENT_HOLE: + type = "hole"; + break; + default: + fprintf(stderr, "invalid extent type %d\n", + extent[i].ex_type); + return(1); + } + + if (!Dflag) { +#if __sgi + fprintf(stdout, "\t%d: [%lld..%lld]: %s", num, +#else + fprintf(stdout, "\t%d: [%d..%d]: %s", num, +#endif + extent[i].ex_offset / 512, + (extent[i].ex_offset + + extent[i].ex_length - 1) / 512, type); + if ((extent[i].ex_offset % 512 != 0) || + (endoff % 512 != 0)) { +#if __sgi + fprintf(stdout, "\t[%lld..%lld]\n", +#else + fprintf(stdout, "\t[%d..%d]\n", +#endif + extent[i].ex_offset % 512, + (endoff-1) % 512); + } else { + fprintf(stdout, "\n"); + } + } else { +#ifdef __sgi + fprintf(stdout, "%5s %13lld %13lld\n", +#else + fprintf(stdout, "%5s %13d %13d\n", +#endif + type, extent[i].ex_offset, + extent[i].ex_length); + } + + /* The ex_offset of the first extent should match the + 'startoff' specified by the caller. The ex_offset + in subsequent extents should always match + (ex_offset + ex_length) of the previous extent, + and should always start on a 512 byte boundary. + */ + + if (extent[i].ex_offset != endoff) { +#ifdef __sgi + fprintf(stderr, "new extent (%lld)is not " + "adjacent to previous one (%lld)\n", +#else + fprintf(stderr, "new extent (%d)is not " + "adjacent to previous one (%d)\n", +#endif + extent[i].ex_offset, endoff); + return(1); + } + if (num && (extent[i].ex_offset % 512) != 0) { +#ifdef __sgi + fprintf(stderr, "non-initial ex_offset (%lld) " +#else + fprintf(stderr, "non-initial ex_offset (%d) " +#endif + "is not a 512-byte multiple\n", + extent[i].ex_offset); + return(1); + } + + /* Non-initial extents should have ex_length values + that are an even multiple of 512. The initial + extent should be a multiple of 512 less the offset + into the starting 512-byte block. + */ + + if (((extent[i].ex_offset % 512) + extent[i].ex_length) % 512 != 0) { + fprintf(stderr, "ex_length is incorrect based " + "upon the ex_offset\n"); + return(1); + } + + endoff = extent[i].ex_offset + extent[i].ex_length; + num++; /* count of extents printed */ + } + + /* If not yet at end of file, the startoff parameter should + match the ex_offset plus ex_length of the last extent + retrieved. + */ + + if (rc && startoff != endoff) { +#ifdef __sgi + fprintf(stderr, "startoff is %lld, should be %lld\n", +#else + fprintf(stderr, "startoff is %d, should be %d\n", +#endif + startoff, endoff); + return(1); + } + + /* If we are at end of file, the last extent should be a + hole. + */ + + if (!rc && type && strcmp(type, "hole")) { + fprintf(stderr, "file didn't end with a hole\n"); + return(1); + } + } + + /* At end of file, startoff should always equal zero. */ + + if (startoff != 0) { + fprintf(stderr, "ERROR: startoff was not zero at end of file\n"); + return(1); + } + return(0); +} diff --git a/dmapi/src/suite1/cmd/get_config_events.c b/dmapi/src/suite1/cmd/get_config_events.c new file mode 100644 index 000000000..abf0926b3 --- /dev/null +++ b/dmapi/src/suite1/cmd/get_config_events.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_get_config_events(). The +command line is: + + get_config_events [-n nelem] handle + +where handle is the handle of a file or filesystem, and nelem is the value +to use for the nelem parameter to dm_get_eventlist(). + +----------------------------------------------------------------------------*/ + +extern int optind; +extern char *optarg; + + +char *Progname; + + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-n nelem] handle\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + u_int nelem = DM_EVENT_MAX; + char *han_str; + dm_eventset_t eventset; + void *hanp; + size_t hlen; + u_int nelemp; + char *name; + int error; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "n:")) != EOF) { + switch (opt) { + case 'n': + nelem = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + han_str = argv[optind]; + if ((error = atohan(han_str, &hanp, &hlen)) != 0) { + fprintf(stderr, "atohan() failed, %s\n", strerror(error)); + return(1); + } + + if (dm_init_service(&name)) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + return(1); + } + + DMEV_ZERO(eventset); + + if (dm_get_config_events(hanp, hlen, nelem, &eventset, &nelemp)) { + fprintf(stderr, "dm_get_config_events failed, %s\n", + strerror(errno)); + return(1); + } + + fprintf(stdout, "Events supported (0x%llx), nelemp %d:\n", + eventset, nelemp); + + for (i = 0; i < nelemp; i++) { + if (!DMEV_ISSET(i, eventset)) + continue; + switch (i) { + case DM_EVENT_CANCEL: + fprintf(stdout, "DM_EVENT_CANCEL"); + break; + case DM_EVENT_MOUNT: + fprintf(stdout, "DM_EVENT_MOUNT"); + break; + case DM_EVENT_PREUNMOUNT: + fprintf(stdout, "DM_EVENT_PREUNMOUNT"); + break; + case DM_EVENT_UNMOUNT: + fprintf(stdout, "DM_EVENT_UNMOUNT"); + break; + case DM_EVENT_DEBUT: + fprintf(stdout, "DM_EVENT_DEBUT"); + break; + case DM_EVENT_CREATE: + fprintf(stdout, "DM_EVENT_CREATE"); + break; + case DM_EVENT_CLOSE: + fprintf(stdout, "DM_EVENT_CLOSE"); + break; + case DM_EVENT_POSTCREATE: + fprintf(stdout, "DM_EVENT_POSTCREATE"); + break; + case DM_EVENT_REMOVE: + fprintf(stdout, "DM_EVENT_REMOVE"); + break; + case DM_EVENT_POSTREMOVE: + fprintf(stdout, "DM_EVENT_POSTREMOVE"); + break; + case DM_EVENT_RENAME: + fprintf(stdout, "DM_EVENT_RENAME"); + break; + case DM_EVENT_POSTRENAME: + fprintf(stdout, "DM_EVENT_POSTRENAME"); + break; + case DM_EVENT_LINK: + fprintf(stdout, "DM_EVENT_LINK"); + break; + case DM_EVENT_POSTLINK: + fprintf(stdout, "DM_EVENT_POSTLINK"); + break; + case DM_EVENT_SYMLINK: + fprintf(stdout, "DM_EVENT_SYMLINK"); + break; + case DM_EVENT_POSTSYMLINK: + fprintf(stdout, "DM_EVENT_POSTSYMLINK"); + break; + case DM_EVENT_READ: + fprintf(stdout, "DM_EVENT_READ"); + break; + case DM_EVENT_WRITE: + fprintf(stdout, "DM_EVENT_WRITE"); + break; + case DM_EVENT_TRUNCATE: + fprintf(stdout, "DM_EVENT_TRUNCATE"); + break; + case DM_EVENT_ATTRIBUTE: + fprintf(stdout, "DM_EVENT_ATTRIBUTE"); + break; + case DM_EVENT_DESTROY: + fprintf(stdout, "DM_EVENT_DESTROY"); + break; + case DM_EVENT_NOSPACE: + fprintf(stdout, "DM_EVENT_NOSPACE"); + break; + case DM_EVENT_USER: + fprintf(stdout, "DM_EVENT_USER"); + break; + case DM_EVENT_MAX: + fprintf(stdout, "DM_EVENT_23"); + break; + } + fprintf(stdout, " (%d)\n", i); + } + + dm_handle_free(hanp, hlen); + return(0); +} diff --git a/dmapi/src/suite1/cmd/get_dirattrs.c b/dmapi/src/suite1/cmd/get_dirattrs.c new file mode 100644 index 000000000..c24736740 --- /dev/null +++ b/dmapi/src/suite1/cmd/get_dirattrs.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_get_dirattrs(). The +command line is: + + get_dirattrs [-b buflen] [-l loc] [-s sid] dirpath + +where dirpath is the name of a directory, buflen is the size of the buffer +to use in the call, loc is a starting location, and sid is the session ID +whose attributes you are interested in. + +----------------------------------------------------------------------------*/ + +extern char *sys_errlist[]; +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-b buflen] [-l loc] [-s sid] dirpath\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_attrloc_t loc = 0; + char *dirpath; + char buffer[100]; + void *bufp; + size_t buflen = 10000; + u_int mask; + size_t rlenp; + void *hanp; + size_t hlen; + char *name; + int error; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "b:l:s:")) != EOF) { + switch (opt) { + case 'b': + buflen = atol(optarg); + break; + case 'l': + loc = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + dirpath = argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the diretory's handle. */ + + if (dm_path_to_handle(dirpath, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s, %s\n", + dirpath, strerror(errno)); + exit(1); + } + + if ((bufp = malloc(buflen == 0 ? 1 : buflen)) == NULL) { + fprintf(stderr, "malloc failed, %s\n", strerror(errno)); + exit(1); + } + + mask = DM_AT_HANDLE|DM_AT_EMASK|DM_AT_PMANR|DM_AT_PATTR|DM_AT_DTIME|DM_AT_CFLAG|DM_AT_STAT; + + if ((error = dm_get_dirattrs(sid, hanp, hlen, DM_NO_TOKEN, mask, + &loc, buflen, bufp, &rlenp)) < 0) { + if (errno == E2BIG) { + fprintf(stderr, "dm_get_dirattrs buffer too small, " + "should be %d bytes\n", rlenp); + } else { + fprintf(stderr, "dm_get_dirattrs failed, %s\n", + strerror(errno)); + } + exit(1); + } + fprintf(stdout, "rc = %d, rlenp is %d, loc is %lld\n", error, + rlenp, loc); + if (rlenp > 0) { + dm_stat_t *statp; + + statp = (dm_stat_t *)bufp; + while (statp != NULL) { + + hantoa((char *)statp + statp->dt_handle.vd_offset, + statp->dt_handle.vd_length, buffer); + fprintf(stdout, "handle %s\n", buffer); + fprintf(stdout, "name %s\n", + (char *)statp + statp->dt_compname.vd_offset); + print_line(statp); + + statp = DM_STEP_TO_NEXT(statp, dm_stat_t *); + } + } + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/get_dmattr.c b/dmapi/src/suite1/cmd/get_dmattr.c new file mode 100644 index 000000000..7001bda2d --- /dev/null +++ b/dmapi/src/suite1/cmd/get_dmattr.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_get_dmattr(). The +command line is: + + get_dmattr [-b buflen] [-s sid] [-t token] pathname attr + +where pathname is the name of a file, buflen is the size of the buffer to use +in the call, attr is the name of the DMAPI attribute, and sid is the session ID +whose attributes you you are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-b buflen] [-s sid] [-t token] " + "pathname attr\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token = DM_NO_TOKEN; + char *pathname; + dm_attrname_t *attrnamep; + void *bufp; + size_t buflen = 10000; + size_t rlenp; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "b:s:t:")) != EOF) { + switch (opt) { + case 'b': + buflen = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case 't': + token = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + pathname = argv[optind++]; + attrnamep = (dm_attrname_t *)argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s, %s\n", + pathname, strerror(errno)); + exit(1); + } + + if (buflen > 0) { + if ((bufp = malloc(buflen)) == NULL) { + fprintf(stderr, "malloc failed, %s\n", strerror(errno)); + exit(1); + } + } + + if (dm_get_dmattr(sid, hanp, hlen, token, attrnamep, buflen, + bufp, &rlenp)) { + if (errno == E2BIG) { + fprintf(stderr, "dm_get_dmattr buffer too small, " + "should be %d bytes\n", rlenp); + } else { + fprintf(stderr, "dm_get_dmattr failed, %s\n", + strerror(errno)); + } + exit(1); + } + fprintf(stdout, "rlenp is %d, value is '%s'\n", rlenp, bufp); + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/get_eventlist.c b/dmapi/src/suite1/cmd/get_eventlist.c new file mode 100644 index 000000000..53740fe4b --- /dev/null +++ b/dmapi/src/suite1/cmd/get_eventlist.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_get_eventlist(). The +command line is: + + get_eventlist [-F] [-n nelem] [-s sid] [-t token] {pathname|handle} + +where: +{pathname|handle} + is the pathname of a file or filesystem or a handle. +-n nelem + is the value to use for the nelem parameter to dm_get_eventlist(). +-s sid + is the dm_sessid_t to use in place of the default test session. +-t token + is the dm_token_t to use in place of DM_NO_TOKEN. +-F + is used when a pathname is specified to indicate that you want its + filesystem handle, not its file handle. + +----------------------------------------------------------------------------*/ + +extern int optind; +extern char *optarg; + + +char *Progname; + + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-F] [-n nelem] [-s sid] [-t token] " + "{pathname|handle}\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token = DM_NO_TOKEN; + u_int nelem = DM_EVENT_MAX; + char *object; + dm_eventset_t eventset; + void *hanp; + size_t hlen; + u_int nelemp; + char *name; + int Fflag = 0; + int error; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fn:s:t:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 'n': + nelem = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case 't': + token = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + object = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + + if ((error = opaque_to_handle(object, &hanp, &hlen)) != 0) { + fprintf(stderr, "can't get a handle from %s, %s\n", + object, strerror(error)); + return(1); + } + + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + DMEV_ZERO(eventset); + + if (dm_get_eventlist(sid, hanp, hlen, token, nelem, + &eventset, &nelemp)) { + fprintf(stderr, "dm_get_eventlist failed, %s\n", + strerror(errno)); + return(1); + } + +#ifdef VERITAS_21 + fprintf(stdout, "Events on object %s (0x%x), nelemp %d:\n", +#else + fprintf(stdout, "Events on object %s (0x%llx), nelemp %d:\n", +#endif + object, eventset, nelemp); + + for (i = 0; i < nelemp; i++) { + if (!DMEV_ISSET(i, eventset)) + continue; + switch (i) { + case DM_EVENT_CANCEL: + fprintf(stdout, "DM_EVENT_CANCEL"); + break; + case DM_EVENT_MOUNT: + fprintf(stdout, "DM_EVENT_MOUNT"); + break; + case DM_EVENT_PREUNMOUNT: + fprintf(stdout, "DM_EVENT_PREUNMOUNT"); + break; + case DM_EVENT_UNMOUNT: + fprintf(stdout, "DM_EVENT_UNMOUNT"); + break; + case DM_EVENT_DEBUT: + fprintf(stdout, "DM_EVENT_DEBUT"); + break; + case DM_EVENT_CREATE: + fprintf(stdout, "DM_EVENT_CREATE"); + break; + case DM_EVENT_CLOSE: + fprintf(stdout, "DM_EVENT_CLOSE"); + break; + case DM_EVENT_POSTCREATE: + fprintf(stdout, "DM_EVENT_POSTCREATE"); + break; + case DM_EVENT_REMOVE: + fprintf(stdout, "DM_EVENT_REMOVE"); + break; + case DM_EVENT_POSTREMOVE: + fprintf(stdout, "DM_EVENT_POSTREMOVE"); + break; + case DM_EVENT_RENAME: + fprintf(stdout, "DM_EVENT_RENAME"); + break; + case DM_EVENT_POSTRENAME: + fprintf(stdout, "DM_EVENT_POSTRENAME"); + break; + case DM_EVENT_LINK: + fprintf(stdout, "DM_EVENT_LINK"); + break; + case DM_EVENT_POSTLINK: + fprintf(stdout, "DM_EVENT_POSTLINK"); + break; + case DM_EVENT_SYMLINK: + fprintf(stdout, "DM_EVENT_SYMLINK"); + break; + case DM_EVENT_POSTSYMLINK: + fprintf(stdout, "DM_EVENT_POSTSYMLINK"); + break; + case DM_EVENT_READ: + fprintf(stdout, "DM_EVENT_READ"); + break; + case DM_EVENT_WRITE: + fprintf(stdout, "DM_EVENT_WRITE"); + break; + case DM_EVENT_TRUNCATE: + fprintf(stdout, "DM_EVENT_TRUNCATE"); + break; + case DM_EVENT_ATTRIBUTE: + fprintf(stdout, "DM_EVENT_ATTRIBUTE"); + break; + case DM_EVENT_DESTROY: + fprintf(stdout, "DM_EVENT_DESTROY"); + break; + case DM_EVENT_NOSPACE: + fprintf(stdout, "DM_EVENT_NOSPACE"); + break; + case DM_EVENT_USER: + fprintf(stdout, "DM_EVENT_USER"); + break; + case DM_EVENT_MAX: + fprintf(stdout, "DM_EVENT_23"); + break; + } + fprintf(stdout, " (%d)\n", i); + } + + dm_handle_free(hanp, hlen); + return(0); +} diff --git a/dmapi/src/suite1/cmd/get_events.c b/dmapi/src/suite1/cmd/get_events.c new file mode 100644 index 000000000..5e437a1c3 --- /dev/null +++ b/dmapi/src/suite1/cmd/get_events.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_get_events(). The +command line is: + + get_events [-b buflen] [-m maxmsgs] [-f] sid + +where buflen is the size of the buffer to use, maxmsgs is the number of messages +to read, -f, if selected, is DM_EV_WAIT, and sid is the session ID +whose dispositions you are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-b buflen] [-m maxmsgs] [-f] sid\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_eventmsg_t *msg; + dm_sessid_t sid; + u_int flags = 0; + void *bufp; + size_t buflen = 10000; + void *hanp; + size_t hlen; + char hans1[HANDLE_STR]; + u_int maxmsgs = 1; + size_t rlenp; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "b:m:f")) != EOF) { + switch (opt) { + case 'b': + buflen = atol(optarg); + break; + case 'm': + maxmsgs = atol(optarg); + break; + case 'f': + flags = DM_EV_WAIT; + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + sid = atol(argv[optind]); + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + + if (buflen > 0) { + if ((bufp = malloc(buflen)) == NULL) { + fprintf(stderr, "malloc failed, %s\n", strerror(errno)); + exit(1); + } + } + + if (dm_get_events(sid, maxmsgs, flags, buflen, bufp, &rlenp)) { + if (errno == E2BIG) { + fprintf(stderr, "dm_get_events buffer too small, " + "should be %d bytes\n", rlenp); + } else { + fprintf(stderr, "dm_get_events failed, (%d)%s\n", + errno, strerror(errno)); + } + exit(1); + } + fprintf(stdout, "rlenp is %d\n", rlenp); + + if (rlenp == 0) + return(0); + + msg = bufp; + while (msg != NULL) { + print_one_message(msg); + msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *); + } + return(0); +} diff --git a/dmapi/src/suite1/cmd/get_fileattr.c b/dmapi/src/suite1/cmd/get_fileattr.c new file mode 100644 index 000000000..e66ae60eb --- /dev/null +++ b/dmapi/src/suite1/cmd/get_fileattr.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include + +#ifdef linux +#include +#endif + +extern int optind; +extern int opterr; +extern char *optarg; + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "Usage: %s [-a|-A] [-s sid] [-t token] pathname\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token = DM_NO_TOKEN; + char buffer[500]; + void *hanp; + size_t hlen; + dm_stat_t dmstat; + char *pathname; + int a_flag = 0; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + opterr = 0; + while ((opt = getopt(argc, argv, "Aas:t:")) != EOF) { + switch (opt) { + case 'A': + a_flag = 2; + break; + case 'a': + a_flag = 1; + break; + case 's': + sid = atol(optarg); + break; + case 't': + token = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) { + usage(); + } + pathname = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + if (!a_flag) { + fprintf(stdout, "path %s\n", pathname); + + /* Get the file's state, print it, then verify it against + what is in the file's stat block. + */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "dm_path_to_handle failed, %s\n", + strerror(errno)); + exit(1); + } + + if (dm_get_fileattr(sid, hanp, hlen, token, + DM_AT_EMASK|DM_AT_PMANR|DM_AT_PATTR|DM_AT_DTIME|DM_AT_CFLAG|DM_AT_STAT, + &dmstat)) { + fprintf(stderr, "dm_get_fileattr failed, %s\n", + strerror(errno)); + exit(1); + } + + print_state(&dmstat); + (void)validate_state(&dmstat, pathname, 1); +/* XXX Shut off for now + } else { + if ((rc = filesys_bulkscan_init(pathname, &scanp)) != 0) { + fprintf(stderr, "filesys_bulkscan failed, %s\n", + fileio_err_image(rc)); + exit(1); + } + for (;;) { + rc = filesys_bulkscan_read(scanp, &fhandle, &fullstat); + if (rc != FILEIO_NOERROR) + break; + + (void)fhandle_to_buffer(&fhandle, buffer, sizeof(buffer)); + if (a_flag == 1) { + fprintf(stdout, "handle %s\n", buffer); + print_state(&fullstat); + fprintf(stdout, "--------------------------\n"); + } else { + fprintf(stdout, "%s|", buffer); + print_line(&fullstat); + } + } + + if (rc != FILEIO_ENDOFSCAN) { + fprintf(stderr, "filesys_bulkscan_read failed, %s\n", + fileio_err_image(rc)); + exit(1); + } + if ((rc = filesys_bulkscan_close(&scanp)) != 0) { + fprintf(stderr, "filesys_bulkscan_close failed, %s\n", + fileio_err_image(rc)); + exit(1); + } +XXX Shut off for now. */ + } +} diff --git a/dmapi/src/suite1/cmd/get_mountinfo.c b/dmapi/src/suite1/cmd/get_mountinfo.c new file mode 100644 index 000000000..763e044ab --- /dev/null +++ b/dmapi/src/suite1/cmd/get_mountinfo.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include + +#include + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_get_mountinfo(). The +command line is: + + get_mountinfo [-b buflen] [-s sid] pathname + +where pathname is the name of a file, buflen is the size of the buffer to use +in the call, and sid is the session ID whose attributes you are interested in. + +----------------------------------------------------------------------------*/ + + /* + * Define some standard formats for the printf statements below. + */ + +#define HDR "%s: token %d sequence %d\n" +#define VALS "\t%-15s %s\n" +#define VALD "\t%-15s %d\n" +#ifdef __sgi +#define VALLLD "\t%-15s %lld\n" +#else +#define VALLLD "\t%-15s %ld\n" +#endif + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-b buflen] [-s sid] pathname\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname; + void *bufp; + size_t buflen = 10000; + size_t rlenp; + void *fshanp; + size_t fshlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "b:s:")) != EOF) { + switch (opt) { + case 'b': + buflen = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_fshandle(pathname, &fshanp, &fshlen)) { + fprintf(stderr, "can't get fshandle for file %s, %s\n", + pathname, strerror(errno)); + exit(1); + } + + if (buflen > 0) { + if ((bufp = malloc(buflen)) == NULL) { + fprintf(stderr, "malloc failed, %s\n", strerror(errno)); + exit(1); + } + } + + if (dm_get_mountinfo(sid, fshanp, fshlen, DM_NO_TOKEN, buflen, + bufp, &rlenp)) { + if (errno == E2BIG) { + fprintf(stderr, "dm_get_mountinfo buffer too small, " + "should be %d bytes\n", rlenp); + } else { + fprintf(stderr, "dm_get_mountinfo failed, %s\n", + strerror(errno)); + } + exit(1); + } + fprintf(stdout, "rlenp is %d\n", rlenp); + print_one_mount_event(bufp); + + dm_handle_free(fshanp, fshlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/get_region.c b/dmapi/src/suite1/cmd/get_region.c new file mode 100644 index 000000000..aa8a6fa25 --- /dev/null +++ b/dmapi/src/suite1/cmd/get_region.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_set_region(). The +command line is: + + get_region [-n nelem] [-s sid] pathname + +where pathname is the name of a file, nelem is the number of regions to pass +in the call, and sid is the session ID whose events you you are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static struct { + char *name; + int value; +} rg_events[3] = { + { "DM_REGION_READ", DM_REGION_READ }, + { "DM_REGION_WRITE", DM_REGION_WRITE }, + { "DM_REGION_TRUNCATE", DM_REGION_TRUNCATE } +}; +static int nevents = sizeof(rg_events)/sizeof(rg_events[0]); + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-n nelem] [-s sid] pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_region_t *regbufp = NULL; + char *pathname = NULL; + u_int nelemp; + u_int nelem = 1; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "n:s:")) != EOF) { + switch (opt) { + case 'n': + nelem = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", pathname); + exit(1); + } + + if (nelem > 0) { + if ((regbufp = calloc(nelem, sizeof(*regbufp))) == NULL) { + fprintf(stderr, "calloc failed, %s\n", strerror(errno)); + exit(1); + } + } + + if (dm_get_region(sid, hanp, hlen, DM_NO_TOKEN, nelem, regbufp, + &nelemp)) { + fprintf(stderr, "dm_get_region failed, %s\n", + strerror(errno)); + exit(1); + } + fprintf(stdout, "%d regions\n", nelemp); + + for (i = 0; i < nelemp; i++) { +#ifdef VERITAS_21 + fprintf(stdout, "offset %d, size %d, flags 0x%x\n", +#else + fprintf(stdout, "offset %lld, size %lld, flags 0x%x\n", +#endif + regbufp[i].rg_offset, regbufp[i].rg_size, + regbufp[i].rg_flags); + } + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/getall_disp.c b/dmapi/src/suite1/cmd/getall_disp.c new file mode 100644 index 000000000..dd0608e59 --- /dev/null +++ b/dmapi/src/suite1/cmd/getall_disp.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_getall_disp(). The +command line is: + + getall_disp [-b buflen] sid + +where buflen is the size of the buffer to use, and sid is the session ID +whose dispositions you you are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-b buflen] sid\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_dispinfo_t *disp; + dm_sessid_t sid; + void *bufp; + size_t buflen = 10000; + void *hanp; + size_t hlen; + char hans1[HANDLE_STR]; + size_t rlenp; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "b:")) != EOF) { + switch (opt) { + case 'b': + buflen = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + sid = atol(argv[optind]); + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + + if (buflen > 0) { + if ((bufp = malloc(buflen)) == NULL) { + fprintf(stderr, "malloc failed, %s\n", strerror(errno)); + exit(1); + } + } + + if (dm_getall_disp(sid, buflen, bufp, &rlenp)) { + if (errno == E2BIG) { + fprintf(stderr, "dm_getall_disp buffer too small, " + "should be %d bytes\n", rlenp); + } else { + fprintf(stderr, "dm_getall_disp failed, %s\n", + strerror(errno)); + } + exit(1); + } + fprintf(stdout, "rlenp is %d\n", rlenp); + if (rlenp == 0) + return(0); + + disp = bufp; + while (disp != NULL) { + hanp = DM_GET_VALUE(disp, di_fshandle, void *); + hlen = DM_GET_LEN(disp, di_fshandle); + if (hanp && hlen) { + hantoa(hanp, hlen, hans1); + } else { + sprintf(hans1, "", hlen); + } + printf("%-15s %s dm_eventset_t 0%llo\n", + "fshandle", hans1, + disp->di_eventset); + + disp = DM_STEP_TO_NEXT(disp, dm_dispinfo_t *); + } + return(0); +} diff --git a/dmapi/src/suite1/cmd/getall_dmattr.c b/dmapi/src/suite1/cmd/getall_dmattr.c new file mode 100644 index 000000000..3c3bc4018 --- /dev/null +++ b/dmapi/src/suite1/cmd/getall_dmattr.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_getall_dmattr(). The +command line is: + + getall_dmattr [-b buflen] [-s sid] pathname + +where pathname is the name of a file, buflen is the size of the buffer to use +in the call, and sid is the session ID whose attributes you are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-b buflen] [-s sid] pathname\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname; + void *bufp; + size_t buflen = 10000; + size_t rlenp; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "b:s:")) != EOF) { + switch (opt) { + case 'b': + buflen = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s, %s\n", + pathname, strerror(errno)); + exit(1); + } + + if ((bufp = malloc(buflen == 0 ? 1 : buflen)) == NULL) { + fprintf(stderr, "malloc failed, %s\n", strerror(errno)); + exit(1); + } + + if (dm_getall_dmattr(sid, hanp, hlen, DM_NO_TOKEN, buflen, + bufp, &rlenp)) { + if (errno == E2BIG) { + fprintf(stderr, "dm_getall_dmattr buffer too small, " + "should be %d bytes\n", rlenp); + } else { + fprintf(stderr, "dm_getall_dmattr failed, %s\n", + strerror(errno)); + } + exit(1); + } + fprintf(stdout, "rlenp is %d\n", rlenp); + if (rlenp > 0) { + dm_attrlist_t *attrlist; + + fprintf(stdout, "DMAPI attributes are:\n"); + + attrlist = (dm_attrlist_t *)bufp; + while (attrlist != NULL) { + fprintf(stdout, "Name: %s, length %d, value '%s'\n", + attrlist->al_name.an_chars, + DM_GET_LEN(attrlist, al_data), + DM_GET_VALUE(attrlist, al_data, char *)); + + attrlist = DM_STEP_TO_NEXT(attrlist, dm_attrlist_t *); + } + } + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/handle_to_fshandle.c b/dmapi/src/suite1/cmd/handle_to_fshandle.c new file mode 100644 index 000000000..b7d33dfa6 --- /dev/null +++ b/dmapi/src/suite1/cmd/handle_to_fshandle.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +/* Given an object's handle, print the filesystem handle. */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test dm_handle_to_fshandle(). The command line is: + + path_to_fshandle handle + +where handle is an object's handle. + +----------------------------------------------------------------------------*/ + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s handle\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *han_str; + char *name; + void *hanp, *fshanp; + size_t hlen, fshlen; + char buffer[100]; + int error; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + if (argc != 2) + usage(); + han_str = argv[1]; + + (void)dm_init_service(&name); + + if ((error = atohan(han_str, &hanp, &hlen)) != 0) { + fprintf(stderr, "atohan() failed, %s\n", strerror(error)); + return(1); + } + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen) != 0) { + fprintf(stderr, "dm_handle_to_fshandle failed, %s\n", + strerror(errno)); + return(1); + } + hantoa(fshanp, fshlen, buffer); + fprintf(stdout, "%s\n", buffer); + + dm_handle_free(hanp, hlen); + dm_handle_free(fshanp, fshlen); + return(0); +} diff --git a/dmapi/src/suite1/cmd/handle_to_path.c b/dmapi/src/suite1/cmd/handle_to_path.c new file mode 100644 index 000000000..305023a8f --- /dev/null +++ b/dmapi/src/suite1/cmd/handle_to_path.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include +#include +#include + +#include + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_handle_to_path(). The +command line is: + + handle_to_path [-b buflen] dirpath objpath + +There are two parameters. The first is the pathname of a directory, +and the second is the pathname of a file, directory, or symbolic link +within that directory. The second parameter can also be the same as +the first if you want to specify "." (this is how EMASS uses it). +Pathnames can either be relative or full. + +buflen is the size of the buffer to use in the call. + +This program will return the full pathname of the object which is the +second parameter using the dm_handle_to_path() function. + +The program should work successfully for files, directories, and +symbolic links, and does not have to work for any other type of +object. It doesn't have to work across mount points. There shouldn't +be any "/." crud on the end of the returned pathname either. + +----------------------------------------------------------------------------*/ + +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-b buflen] dirpath objpath\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *dirpath; + char *objpath; + void *hanp1, *hanp2, *hanp1a; + size_t hlen1, hlen2, hlen1a; + void *pathbufp; + size_t buflen = 1024; + size_t rlenp; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "b:")) != EOF) { + switch (opt) { + case 'b': + buflen = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + dirpath = argv[optind++]; + objpath = argv[optind]; + + if (dm_init_service(&name)) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + return(1); + } + +printf("about to call dm_path_to_handle for %s\n", dirpath); + if (dm_path_to_handle(dirpath, &hanp1, &hlen1)) { + fprintf(stderr, "dm_path_to_handle failed for %s, (%d) %s\n", + dirpath, errno, strerror(errno)); + return(1); + } +printf("about to call path_to_handle for %s\n", dirpath); + if (path_to_handle(dirpath, &hanp1a, &hlen1a)) { + fprintf(stderr, "path_to_handle failed for %s, (%d) %s\n", + dirpath, errno, strerror(errno)); + return(1); + } + if(hlen1 != hlen1a){ + fprintf(stderr, "dm_path_to_handle != path_to_handle, %d != %d\n", + hlen1, hlen1a); + } + if( memcmp(hanp1, hanp1a, hlen1) != 0 ){ + fprintf(stderr, "dm_path_to_handle != path_to_handle, handles differ\n"); + } +printf("about to call dm_path_to_handle for %s\n", objpath); + if (dm_path_to_handle(objpath, &hanp2, &hlen2)) { + fprintf(stderr, "dm_path_to_handle failed for %s, (%d) %s\n", + objpath, errno, strerror(errno)); + return(1); + } + + if ((pathbufp = malloc(buflen == 0 ? 1 : buflen)) == NULL) { + fprintf(stderr, "malloc failed\n"); + return(1); + } + +printf("about to call handle_to_path\n"); + if (dm_handle_to_path(hanp1, hlen1, hanp2, hlen2, + buflen, pathbufp, &rlenp)) { + if (errno == E2BIG) { + fprintf(stderr, "dm_handle_to_path buffer too small, " + "should be %d bytes\n", rlenp); + } else { + fprintf(stderr, "dm_handle_to_path failed, (%d) %s\n", + errno, strerror(errno)); + } + return(1); + } + fprintf(stderr, "rlenp is %d, pathbufp is %s\n", rlenp, pathbufp); + if (strlen(pathbufp) + 1 != rlenp) { + fprintf(stderr, "rlenp is %d, should be %d\n", rlenp, + strlen(pathbufp) + 1); + return(1); + } +} diff --git a/dmapi/src/suite1/cmd/init_service.c b/dmapi/src/suite1/cmd/init_service.c new file mode 100644 index 000000000..c9843d2d0 --- /dev/null +++ b/dmapi/src/suite1/cmd/init_service.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test dm_init_service(). The command line is: + + init_service + +----------------------------------------------------------------------------*/ + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *name; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + if (argc != 1) + usage(); + + (void)dm_init_service(&name); + fprintf(stdout, "%s\n", name); + + return(0); +} diff --git a/dmapi/src/suite1/cmd/link_test.c b/dmapi/src/suite1/cmd/link_test.c new file mode 100644 index 000000000..e63a2adaa --- /dev/null +++ b/dmapi/src/suite1/cmd/link_test.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +/* + The variable 'flags' was used with two different meanings within + the spec. Sometimes it was an int, and sometimes a u_int. I + changed all the u_int references to use the new symbol uflags. + + The variable 'rlenp' was also used with two different meanings; + sometimes size_t, and sometimes dm_size_t. I introduced the new + symbol 'dmrlenp' for the dm_size_t cases. +*/ + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid, oldsid, targetsid, *newsidp, *sidbufp; + dm_token_t token, *tokenp, *rtokenp, *tokenbufp; + dm_attrname_t *attrnamep; + dm_off_t off, *offp, *roffp; + dm_extent_t *extentp; + dm_inherit_t *inheritbufp; + dm_stat_t *statp; + dm_size_t len, *dmrlenp, *retvalp; + dm_attrloc_t *locp; + dm_eventset_t *eventsetp; + dm_config_t flagname; + dm_region_t *regbufp; + dm_response_t response; + dm_right_t right, *rightp; + dm_igen_t igen, *igenp; + dm_msgtype_t msgtype; + dm_fileattr_t *attrp; + dm_boolean_t enable, *exactflagp; + dm_timestruct_t *delay; + mode_t mode; + size_t hlen, dirhlen, hlen1, hlen2, targhlen, *fshlenp, *hlenp; + size_t msglen, buflen, *rlenp; + u_int nelem, mask, maxmsgs, uflags, *nelemp, maxevent; + void *hanp, *dirhanp, *hanp1, *hanp2, *targhanp; + void *msgdatap, *bufp, **hanpp, *respbufp, **fshanpp; + dm_fsid_t fsid, *fsidp; + dm_ino_t ino, *inop; + char *cname, *sessinfop, *path, *pathbufp, **versionstrpp; + int flags, fd, setdtime, reterror; + u_int urc; + int rc; + dm_ssize_t ssrc; + +/* Definitions per the prototypes in dmport.h, in the same order. */ + + rc = dm_clear_inherit(sid, hanp, hlen, token, attrnamep); + rc = dm_create_by_handle(sid, dirhanp, dirhlen, token, + hanp, hlen, cname); + rc = dm_create_session(oldsid, sessinfop, newsidp); + rc = dm_create_userevent(sid, msglen, msgdatap, tokenp); + rc = dm_destroy_session(sid); + rc = dm_downgrade_right(sid, hanp, hlen, token); + rc = dm_fd_to_handle(fd, hanpp, hlenp); + rc = dm_find_eventmsg(sid, token, buflen, bufp, rlenp); + rc = dm_get_allocinfo(sid, hanp, hlen, + token, offp, nelem, extentp, nelemp); + rc = dm_get_bulkall(sid, hanp, hlen, token, mask, attrnamep, + locp, buflen, bufp, rlenp); + rc = dm_get_bulkattr(sid, hanp, hlen, token, mask, locp, buflen, + bufp, rlenp); + rc = dm_get_config(hanp, hlen, flagname, retvalp); + rc = dm_get_config_events(hanp, hlen, nelem, eventsetp, nelemp); + rc = dm_get_dirattrs(sid, hanp, hlen, token, mask, locp, buflen, + bufp, rlenp); + rc = dm_get_dmattr(sid, hanp, hlen, token, attrnamep, buflen, + bufp, rlenp); + rc = dm_get_eventlist(sid, hanp, hlen, token, nelem, eventsetp, nelemp); + rc = dm_get_events(sid, maxmsgs, flags, buflen, bufp, rlenp); + rc = dm_get_fileattr(sid, hanp, hlen, token, mask, statp); + rc = dm_get_mountinfo(sid, hanp, hlen, token, buflen, bufp, rlenp); + rc = dm_get_region(sid, hanp, hlen, token, nelem, regbufp, nelemp); + rc = dm_getall_disp(sid, buflen, bufp, rlenp); + rc = dm_getall_dmattr(sid, hanp, hlen, token, buflen, bufp, rlenp); + rc = dm_getall_inherit(sid, hanp, hlen, + token, nelem, inheritbufp, nelemp); + rc = dm_getall_sessions(nelem, sidbufp, nelemp); + rc = dm_getall_tokens(sid, nelem, tokenbufp, nelemp); + rc = dm_handle_cmp(hanp1, hlen1, hanp2, hlen2); + dm_handle_free(hanp, hlen); + urc = dm_handle_hash(hanp, hlen); + rc = dm_handle_is_valid(hanp, hlen); + rc = dm_handle_to_fshandle(hanp, hlen, fshanpp, fshlenp); + rc = dm_handle_to_fsid(hanp, hlen, fsidp); + rc = dm_handle_to_igen(hanp, hlen, igenp); + rc = dm_handle_to_ino(hanp, hlen, inop); + rc = dm_handle_to_path(dirhanp, dirhlen, targhanp, targhlen, + buflen, pathbufp, rlenp); + rc = dm_init_attrloc(sid, hanp, hlen, token, locp); + rc = dm_init_service(versionstrpp); + rc = dm_make_handle(&fsid, &ino, &igen, hanpp, hlenp); + rc = dm_make_fshandle(&fsid, hanpp, hlenp); + rc = dm_mkdir_by_handle(sid, dirhanp, dirhlen, token, + hanp, hlen, cname); + rc = dm_move_event(sid, token, targetsid, rtokenp); + rc = dm_obj_ref_hold(sid, token, hanp, hlen); + rc = dm_obj_ref_query(sid, token, hanp, hlen); + rc = dm_obj_ref_rele(sid, token, hanp, hlen); + rc = dm_path_to_fshandle(path, hanpp, hlenp); + rc = dm_path_to_handle(path, hanpp, hlenp); + rc = dm_pending(sid, token, delay); + rc = dm_probe_hole(sid, hanp, hlen, token, off, len, roffp, dmrlenp); + rc = dm_punch_hole(sid, hanp, hlen, token, off, len); + rc = dm_query_right(sid, hanp, hlen, token, rightp); + rc = dm_query_session(sid, buflen, bufp, rlenp); + ssrc = dm_read_invis(sid, hanp, hlen, token, off, len, bufp); + rc = dm_release_right(sid, hanp, hlen, token); + rc = dm_remove_dmattr(sid, hanp, hlen, token, setdtime, attrnamep); + rc = dm_request_right(sid, hanp, hlen, token, uflags, right); + rc = dm_respond_event(sid, token, response, reterror, buflen, respbufp); + rc = dm_send_msg(sid, msgtype, buflen, bufp); + rc = dm_set_disp(sid, hanp, hlen, token, eventsetp, maxevent); + rc = dm_set_dmattr(sid, hanp, hlen, + token, attrnamep, setdtime, buflen, bufp); + rc = dm_set_eventlist(sid, hanp, hlen, token, eventsetp, maxevent); + rc = dm_set_fileattr(sid, hanp, hlen, token, mask, attrp); + rc = dm_set_inherit(sid, hanp, hlen, token, attrnamep, mode); + rc = dm_set_region(sid, hanp, hlen, token, nelem, regbufp, exactflagp); + rc = dm_set_return_on_destroy(sid, hanp, hlen, + token, attrnamep, enable); + rc = dm_symlink_by_handle(sid, dirhanp, dirhlen, token, + hanp, hlen, cname, path); + rc = dm_sync_by_handle(sid, hanp, hlen, token); + rc = dm_upgrade_right(sid, hanp, hlen, token); + ssrc = dm_write_invis(sid, hanp, hlen, flags, token, off, len, bufp); +} diff --git a/dmapi/src/suite1/cmd/make_rt_sparse.c b/dmapi/src/suite1/cmd/make_rt_sparse.c new file mode 100644 index 000000000..078d12bba --- /dev/null +++ b/dmapi/src/suite1/cmd/make_rt_sparse.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +/* + * Create file with XFS_XFLAG_REALTIME set. + */ + +#include +/* #include */ +#ifdef linux +#else +#include +#include +#include +#endif + +#include +#include +#include +#include +#include + + +/* Note: In order to figure out the filesystem geometry, you have to run this + program as root. Creating the file itself can be done by anyone. +*/ + + +static char * prog; + +static void +Usage(void) +{ + fprintf(stderr,"Usage: %s filename\n", prog); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + xfs_fsop_geom_t geom; + struct fsxattr fsx; + struct dioattr dio; + char *pathname; + u_int buflen; + char *buf; + ssize_t offset; + ssize_t count; + int fd; + int i; + + if (prog = strrchr(argv[0], '/')) { + *prog++; + } else { + prog = argv[0]; + } + + if (argc != 2) + Usage(); + pathname = argv[1]; + + /* Create the file. */ + + if ((fd = open(pathname, O_RDWR|O_CREAT|O_EXCL|O_DIRECT, 0600)) < 0) { + fprintf(stderr,"%s: Cannot open %s, %s\n", prog, + pathname, strerror(errno)); + exit(1); + } + + /* Determine the filesystem's realtime partition geometry. */ + + if (syssgi(SGI_XFS_FSOPERATIONS, fd, XFS_FS_GEOMETRY, NULL, &geom)) { + fprintf(stderr,"%s: syssgi(,XFS_FS_GEOMETRY) failed, %s\n", + prog, strerror(errno)); + exit(1); + } + + /* Make the file a realtime file. */ + + fsx.fsx_xflags = 1; /*XFS_XFLAG_REALTIME*/ + fsx.fsx_extsize = 4 * geom.blocksize * geom.rtextsize; + if (fcntl(fd, F_FSSETXATTR, &fsx) < 0) { + fprintf(stderr,"%s: fcntl(,F_FSSETXATTR) failed, %s\n", prog, + strerror(errno)); + exit(1); + } + + /* Obtain the direct I/O parameters. */ + + if (fcntl(fd, F_DIOINFO, &dio) < 0) { + fprintf(stderr,"%s: fcntl(,F_DIOINFO) failed,%s\n", + prog, strerror(errno)); + exit(1); + } + fprintf(stdout, "%s: file %s direct io requirements.\n", prog, + pathname); + fprintf(stdout, "%7d memory alignment.\n", dio.d_mem); + fprintf(stdout, "%7d minimum io size.\n", dio.d_miniosz); + fprintf(stdout, "%7d maximum io size.\n", dio.d_maxiosz); + + if (fcntl(fd, F_FSGETXATTR, &fsx) < 0) { + fprintf(stderr,"%s: fcntl(,F_FSGETXATTR) failed, %s\n", prog, + strerror(errno)); + exit(1); + } + fprintf(stdout, "%7d realtime extent size.\n", fsx.fsx_extsize); + + /* Malloc and zero a buffer to use for writes. */ + + buflen = dio.d_miniosz; + if ((buf = memalign(dio.d_mem, buflen)) == NULL) { + fprintf(stderr,"%s: memalign(%d,%d) returned NULL\n", + prog, dio.d_mem, buflen); + exit(1); + } + memset(buf, '\0', buflen); + + for (i = 0; i < 10; i += 2) { + offset = i * fsx.fsx_extsize; + if (lseek(fd, offset, SEEK_SET) < 0) { + fprintf(stderr, "seek to %d failed, %s\n", offset, + strerror(errno)); + exit(1); + } + if ((count = write(fd, buf, buflen)) < 0) { + fprintf(stderr, "write of %d bytes failed at offset " + "%d, , %s\n", buflen, offset, strerror(errno)); + exit(1); + } + if (count != buflen) { + fprintf(stderr, "expected to write %d bytes at offset " + "%d, actually wrote %d\n", buflen, offset, + count); + exit(1); + } + } + exit(0); +} diff --git a/dmapi/src/suite1/cmd/make_sparse.c b/dmapi/src/suite1/cmd/make_sparse.c new file mode 100644 index 000000000..0869b3d80 --- /dev/null +++ b/dmapi/src/suite1/cmd/make_sparse.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +/* + * + */ + +#include + +#include +#include +#include +#include +#include + + +static char * prog; + +static void +Usage(void) +{ + fprintf(stderr,"Usage: %s filename\n", prog); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *pathname; + u_int buflen; + char *buf; + ssize_t offset; + ssize_t count; + int fd; + int i; + + prog = argv[0]; + + if (argc != 2) + Usage(); + pathname = argv[1]; + + /* Create the file and make it a regular file. */ + + if ((fd = open(pathname, O_RDWR|O_CREAT|O_EXCL, 0600)) < 0) { + fprintf(stderr,"%s: Cannot open %s, %s\n", prog, + pathname, strerror(errno)); + exit(1); + } + + /* Malloc and zero a buffer to use for writes. */ + + buflen = 1; + if ((buf = malloc(buflen)) == NULL) { + fprintf(stderr,"%s: malloc(%d) returned NULL\n", + prog, buflen); + exit(1); + } + memset(buf, '\0', buflen); + + for (i = 0; i < 200; i += 2) { + offset = i * 65536; + if (lseek(fd, offset, SEEK_SET) < 0) { + fprintf(stderr, "seek to %d failed, %s\n", offset, + strerror(errno)); + exit(1); + } + if ((count = write(fd, buf, buflen)) < 0) { + fprintf(stderr, "write of %d bytes failed at offset " + "%d, , %s\n", buflen, offset, strerror(errno)); + exit(1); + } + if (count != buflen) { + fprintf(stderr, "expected to write %d bytes at offset " + "%d, actually wrote %d\n", buflen, offset, + count); + exit(1); + } + } + exit(0); +} diff --git a/dmapi/src/suite1/cmd/obj_ref_hold.c b/dmapi/src/suite1/cmd/obj_ref_hold.c new file mode 100644 index 000000000..e962a1ded --- /dev/null +++ b/dmapi/src/suite1/cmd/obj_ref_hold.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_obj_ref_hold(). The +command line is: + + obj_ref_hold {-F} [-s sid] token {pathname|handle} + +where: +-F + when a pathname is specified, -F indicates that its filesystem handle + should be used rather than its file object handle. +sid + is the dm_sessid_t to use rather than the default test session. +token + is the dm_token_t to use. +{pathname|handle} + is either a handle, or is the pathname of a file whose handle is + to be used. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-F] [-s sid] token {pathname|handle}\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token; + char *object; + void *hanp; + size_t hlen; + int Fflag = 0; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fs:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + token = atol(argv[optind++]); + object = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file or filesystem's handle. */ + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle from %s\n", object); + exit(1); + } + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + if (dm_obj_ref_hold(sid, token, hanp, hlen)) { + fprintf(stderr, "dm_obj_ref_hold failed, %s\n", + strerror(errno)); + return(1); + } + + dm_handle_free(hanp, hlen); +} diff --git a/dmapi/src/suite1/cmd/obj_ref_query.c b/dmapi/src/suite1/cmd/obj_ref_query.c new file mode 100644 index 000000000..df4055ea7 --- /dev/null +++ b/dmapi/src/suite1/cmd/obj_ref_query.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_obj_ref_query(). The +command line is: + + obj_ref_query {-F} [-s sid] token {pathname|handle} + +where: +-F + when a pathname is specified, -F indicates that its filesystem handle + should be used rather than its file object handle. +sid + is the dm_sessid_t to use rather than the default test session. +token + is the dm_token_t to use. +{pathname|handle} + is either a handle, or is the pathname of a file whose handle is + to be used. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-F] [-s sid] token {pathname|handle}\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token; + char *object; + void *hanp; + size_t hlen; + int Fflag = 0; + char *name; + int error; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fs:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + token = atol(argv[optind++]); + object = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file or filesystem's handle. */ + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle from %s\n", object); + exit(1); + } + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + if ((error = dm_obj_ref_query(sid, token, hanp, hlen)) < 0) { + fprintf(stderr, "dm_obj_ref_query failed, %s\n", + strerror(errno)); + return(1); + } + + if (error == 1) { + fprintf(stdout, "there is a hold\n"); + } else { + fprintf(stdout, "there is no hold\n"); + } + dm_handle_free(hanp, hlen); +} diff --git a/dmapi/src/suite1/cmd/obj_ref_rele.c b/dmapi/src/suite1/cmd/obj_ref_rele.c new file mode 100644 index 000000000..ca88bbb64 --- /dev/null +++ b/dmapi/src/suite1/cmd/obj_ref_rele.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_obj_ref_rele(). The +command line is: + + obj_ref_rele {-F} [-s sid] token {pathname|handle} + +where: +-F + when a pathname is specified, -F indicates that its filesystem handle + should be used rather than its file object handle. +sid + is the dm_sessid_t to use rather than the default test session. +token + is the dm_token_t to use. +{pathname|handle} + is either a handle, or is the pathname of a file whose handle is + to be used. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-F] [-s sid] token {pathname|handle}\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token; + char *object; + void *hanp; + size_t hlen; + int Fflag = 0; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fs:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + token = atol(argv[optind++]); + object = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file or filesystem's handle. */ + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle from %s\n", object); + exit(1); + } + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + if (dm_obj_ref_rele(sid, token, hanp, hlen)) { + fprintf(stderr, "dm_obj_ref_rele failed, %s\n", + strerror(errno)); + return(1); + } + + dm_handle_free(hanp, hlen); +} diff --git a/dmapi/src/suite1/cmd/path_to_fshandle.c b/dmapi/src/suite1/cmd/path_to_fshandle.c new file mode 100644 index 000000000..329dcd791 --- /dev/null +++ b/dmapi/src/suite1/cmd/path_to_fshandle.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +/* Given a file object's pathname, print the filesystem handle. */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test dm_path_to_fshandle(). The command line is: + + path_to_fshandle pathname + +where pathname is the name of a file, directory, or symlink. + +----------------------------------------------------------------------------*/ + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *pathname; + char *name; + void *fshanp; + size_t fshlen; + char buffer[100]; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + if (argc != 2) + usage(); + pathname = argv[1]; + + (void)dm_init_service(&name); + + if (dm_path_to_fshandle(pathname, &fshanp, &fshlen) != 0) { + fprintf(stderr, "dm_path_to_fshandle failed, %s\n", + strerror(errno)); + return(1); + } + hantoa(fshanp, fshlen, buffer); + fprintf(stdout, "%s\n", buffer); + + dm_handle_free(fshanp, fshlen); + return(0); +} diff --git a/dmapi/src/suite1/cmd/path_to_handle.c b/dmapi/src/suite1/cmd/path_to_handle.c new file mode 100644 index 000000000..162d64af5 --- /dev/null +++ b/dmapi/src/suite1/cmd/path_to_handle.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +/* Given a file object's pathname, print the object's handle. */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test dm_path_to_handle(). The command line is: + + path_to_handle pathname + +where pathname is the name of a file, directory, or symlink. + +----------------------------------------------------------------------------*/ + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *pathname; + char *name; + void *hanp; + size_t hlen; + char buffer[100]; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + if (argc != 2) + usage(); + pathname = argv[1]; + + (void)dm_init_service(&name); + + if (dm_path_to_handle(pathname, &hanp, &hlen) != 0) { + fprintf(stderr, "dm_path_to_handle failed, %s\n", + strerror(errno)); + return(1); + } + hantoa(hanp, hlen, buffer); + fprintf(stdout, "%s\n", buffer); + + dm_handle_free(hanp, hlen); + return(0); +} diff --git a/dmapi/src/suite1/cmd/pending.c b/dmapi/src/suite1/cmd/pending.c new file mode 100644 index 000000000..2c1c0d6d9 --- /dev/null +++ b/dmapi/src/suite1/cmd/pending.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_pending(). The +command line is: + + pending sid token + +where sid is the session ID whose event you are responding to. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s sid token\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid; + char *name; + dm_token_t token; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + if (argc != 3) + usage(); + + sid = atol(argv[1]); + token = atol(argv[2]); + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + + if (dm_pending(sid, token, NULL)) { + fprintf(stderr, "dm_pending failed, %s\n", strerror(errno)); + exit(1); + } + exit(0); +} diff --git a/dmapi/src/suite1/cmd/print_event.c b/dmapi/src/suite1/cmd/print_event.c new file mode 100644 index 000000000..f2e67a99d --- /dev/null +++ b/dmapi/src/suite1/cmd/print_event.c @@ -0,0 +1,1198 @@ + + +/* + * eventloop.c + * + * Joseph Jackson + * 25-Jun-1996 + * + * Monitor all events for a file system. + * When one arrives, print a message with all the details. + * If the message is synchronous, always reply with DM_RESP_CONTINUE + * (This program doesn't perform any real file system or HSM work.) + * + * This is a simplification of the "migin.c" example program. + * The original code was by Peter Lawthers: + * This code was written by Peter Lawthers, and placed in the public + * domain for use by DMAPI implementors and app writers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + /* + * Define some standard formats for the printf statements below. + */ + +#define HDR "%s: token %d sequence %d\n" +#define VALS "\t%-15s %s\n" +#define VALD "\t%-15s %d\n" +#ifdef __sgi +#define VALLLD "\t%-15s %lld\n" +#else +#define VALLLD "\t%-15s %ld\n" +#endif + +extern int optind; +extern int errno; + +void usage (char *); +int main (int, char **); +static void event_loop (dm_sessid_t, int); +int handle_message (dm_sessid_t, dm_eventmsg_t *); +static int format_mode(mode_t mode, char **ptr); +static int get_fs_handle (char *, void **, size_t *); +static int set_disposition(dm_sessid_t, void *, size_t); +static int set_events (dm_sessid_t, void *, size_t); +static int clear_events (dm_sessid_t, void *, size_t); +int finish_responding(dm_sessid_t); +int establish_handler(void); +void exit_handler (void); + +#define MAXNAMELEN 256 + +/* + * Keep these global so the exit_handler and err_msg routines can get to them + */ +char *Progname; +int Sleep = 0; +int Verbose; +dm_sessid_t sid = 0; +dm_sessid_t oldsid = 0; +char *fsname; + + +void +usage( + char *prog) +{ + fprintf(stderr, "Usage: %s ", prog); + fprintf(stderr, " <-S oldsid> <-v verbose> "); + fprintf(stderr, "filesystem \n"); +} + + +int +main( + int argc, + char *argv[]) +{ + + int c; + int error; + void *fs_hanp; + size_t fs_hlen; + + +/* Progname = argv[0];*/ Progname = "print_event"; + fsname = NULL; + + while ((c = getopt(argc, argv, "vs:S:")) != EOF) { + switch (c) { + case 's': + Sleep = atoi(optarg); + break; + case 'S': + oldsid = atoi(optarg); + break; + case 'v': + Verbose = 1; + break; + case '?': + default: + usage(Progname); + exit(1); + } + } + if (optind >= argc) { + usage(Progname); + exit(1); + } + fsname = argv[optind]; + if (fsname == NULL) { + usage(Progname); + exit(1); + } + + /* + * Establish an exit handler + */ + error = establish_handler(); + if (error) + exit(1); + + /* + * Init the dmapi, and get a filesystem handle so + * we can set up our events + */ + + if (oldsid) { + sid = oldsid; + } else { + error = setup_dmapi(&sid); + if (error) + exit(1); + } + + error = get_fs_handle(fsname, &fs_hanp, &fs_hlen); + if (error) + goto cleanup; + + /* + * Set the event disposition so that our session will receive + * all the events for the given file system + */ + error = set_disposition(sid, fs_hanp, fs_hlen); + if (error) + goto cleanup; + + /* + * Enable monitoring for all events in the given file system + */ + error = set_events(sid, fs_hanp, fs_hlen); + if (error) + goto cleanup; + + /* + * Now sit in an infinite loop, reporting on any events that occur. + * The program is exited after a signal through exit_handler(). + */ + printf("\n"); + event_loop(sid, 1 /*waitflag*/); + + /* + * If we get here, cleanup after the event_loop failure + */ + cleanup: + exit_handler(); + return(1); +} + + +/* + * Main event loop processing + * + * The waitflag argument is set to 1 when we call this from main(). + * In this case, continuously process incoming events, + * blocking if there are none available. + * In the exit_handler(), call this routine with waitflag=0. + * Just try to read the events once in this case with no blocking. + */ + +static void +event_loop( + dm_sessid_t sid, + int waitflag) +{ + void *msgbuf; + size_t bufsize; + int error; + dm_eventmsg_t *msg; + int count; + + /* + * We take a swag at a buffer size. If it's wrong, we can + * always resize it + */ + + bufsize = sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + HANDLE_LEN; + bufsize *= 50; + msgbuf = (void *)malloc(bufsize); + if (msgbuf == NULL) { + err_msg("Can't allocate memory for buffer"); + return; + } + + for (;;) { + error = dm_get_events(sid, ALL_AVAIL_MSGS, + waitflag ? DM_EV_WAIT:0, bufsize, msgbuf, &bufsize); + if (error) { + if (errno == EAGAIN) { + if (waitflag) + continue; + break; + } + if (errno == E2BIG) { + free(msgbuf); + msgbuf = (void *)malloc(bufsize); + if (msgbuf == NULL) { + err_msg("Can't resize msg buffer"); + return; + } + continue; + } + errno_msg("Error getting events from DMAPI (%d)", errno); + break; + } + + /* + * Walk through the message buffer, pull out each individual + * message, and dispatch the messages to handle_message(), + * which will respond to the events. + */ + + count = 0; + msg = (dm_eventmsg_t *)msgbuf; + while (msg != NULL ) { + count++; + error = handle_message(sid, msg); + if (error) { + free(msgbuf); + return; + } + msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *); + } + if (count != 1 && Verbose) { + err_msg("Found %d events in one call to " + "dm_get_events\n", count); + } + } + if (msgbuf != NULL) + free(msgbuf); +} + + +void +print_one_mount_event( + void *msg) +{ + void *hanp1, *hanp2, *hanp3; + size_t hlen1, hlen2, hlen3; + char hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR]; + void *namp1, *namp2; + size_t nlen1, nlen2; + char nams1[MAXNAMELEN], nams2[MAXNAMELEN]; + mode_t mode; + +#if VERITAS_21 + dm_namesp_event_t *msg_ne = (dm_namesp_event_t *)msg; + +/* + msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *); +*/ + hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *); + hlen1 = DM_GET_LEN (msg_ne, ne_handle1); + hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *); + hlen2 = DM_GET_LEN (msg_ne, ne_handle2); + namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *); + nlen1 = DM_GET_LEN (msg_ne, ne_name1); + namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *); + nlen2 = DM_GET_LEN (msg_ne, ne_name2); + hanp3 = NULL; + hlen3 = 0; + mode = msg_ne->ne_mode; +#else + dm_mount_event_t *msg_me = (dm_mount_event_t *)msg; + + hanp1 = DM_GET_VALUE(msg_me, me_handle1, void *); + hlen1 = DM_GET_LEN(msg_me, me_handle1); + hanp2 = DM_GET_VALUE(msg_me, me_handle2, void *); + hlen2 = DM_GET_LEN(msg_me, me_handle2); + namp1 = DM_GET_VALUE(msg_me, me_name1, void *); + nlen1 = DM_GET_LEN(msg_me, me_name1); + namp2 = DM_GET_VALUE(msg_me, me_name2, void *); + nlen2 = DM_GET_LEN(msg_me, me_name2); + hanp3 = DM_GET_VALUE(msg_me, me_roothandle, void *); + hlen3 = DM_GET_LEN(msg_me, me_roothandle); + mode = msg_me->me_mode; +#endif /* VERITAS_21 */ + + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } else { + sprintf(hans1, "", hlen1); + } + if (hanp2 && hlen2) { + hantoa(hanp2, hlen2, hans2); + } else { + sprintf(hans2, "", hlen2); + } + if (hanp3 && hlen3) { + hantoa(hanp3, hlen3, hans3); + } else { + sprintf(hans3, "", hlen3); + } + if (namp1 && nlen1) { + strncpy(nams1, namp1, nlen1); + if (nlen1 != sizeof(nams1)) + nams1[nlen1] = '\0'; + } else { + sprintf(nams1, "", nlen1); + } + if (namp2 && nlen2) { + strncpy(nams2, namp2, nlen2); + if (nlen2 != sizeof(nams2)) + nams2[nlen2] = '\0'; + } else { + sprintf(nams2, "", nlen2); + } + + printf(VALS VALS VALS VALS VALS VALD, + "fs handle", hans1, + "mtpt handle", hans2, + "mtpt path", nams1, + "media desig", nams2, + "root handle", hans3, + "mode", mode); +} + + +/* + * First, weed out the events which return interesting structures. + * If it's not one of those, unpack the dm_namesp_event structure + * and display the contents. + */ +int +handle_message( + dm_sessid_t sid, + dm_eventmsg_t *msg) +{ + int pkt_error = 0; + int error; + int respond, response, respcode; + dm_namesp_event_t *msg_ne; +#if !VERITAS_21 + dm_mount_event_t *msg_me; +#endif + void *hanp1, *hanp2, *namp1, *namp2; + u_int hlen1, hlen2, nlen1, nlen2; + char hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR]; + char nams1[MAXNAMELEN], nams2[MAXNAMELEN]; + + /* + * Set the defaults for responding to events + */ + respond = 1; + response = DM_RESP_CONTINUE; + respcode = 0; + + /***** USER EVENTS *****/ + + if (msg->ev_type == DM_EVENT_USER) { + char *privp; + u_int plen, i; + + printf(HDR, + "user", msg->ev_token, msg->ev_sequence); + + /* print private data as ascii or hex if it exists DM_CONFIG_MAX_MESSAGE_DATA */ + + privp = DM_GET_VALUE(msg, ev_data, char *); + plen = DM_GET_LEN (msg, ev_data); + if (plen) { + for (i = 0; i < plen; i++) { + if (!isprint(privp[i]) && !isspace(privp[i])) + break; + } + if (i == plen - 1 && privp[i] == '\0') { + printf(VALS, + "privdata", privp); + } else { + printf("\t%-15s ", "privdata"); + for (i = 0; i < plen; i++) { + printf("%.2x", privp[i]); + } + printf("\n"); + } + } else { + printf(VALS, + "privdata", ""); + } + + if (msg->ev_token == DM_INVALID_TOKEN) /* async dm_send_msg event */ + respond = 0; + } + + /***** CANCEL EVENT *****/ + +/* Not implemented on SGI or Veritas */ + + else if (msg->ev_type == DM_EVENT_CANCEL) { + dm_cancel_event_t *msg_ce; + + msg_ce = DM_GET_VALUE(msg, ev_data, dm_cancel_event_t *); + printf(HDR VALD VALD, + "cancel", msg->ev_token, msg->ev_sequence, + "sequence", msg_ce->ce_sequence, + "token", msg_ce->ce_token); + respond = 0; + } + + /***** DATA EVENTS *****/ + + else if (msg->ev_type == DM_EVENT_READ || + msg->ev_type == DM_EVENT_WRITE || + msg->ev_type == DM_EVENT_TRUNCATE) { + dm_data_event_t *msg_de; + + msg_de = DM_GET_VALUE(msg, ev_data, dm_data_event_t *); + hanp1 = DM_GET_VALUE(msg_de, de_handle, void *); + hlen1 = DM_GET_LEN (msg_de, de_handle); + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } else { + sprintf(hans1, "", hlen1); + } + + switch(msg->ev_type) { + + case DM_EVENT_READ: + printf(HDR VALS VALLLD VALLLD, + "read", msg->ev_token, msg->ev_sequence, + "file handle", hans1, + "offset", msg_de->de_offset, + "length", msg_de->de_length); + break; + + case DM_EVENT_WRITE: + printf(HDR VALS VALLLD VALLLD, + "write", msg->ev_token, msg->ev_sequence, + "file handle", hans1, + "offset", msg_de->de_offset, + "length", msg_de->de_length); + break; + + case DM_EVENT_TRUNCATE: + printf(HDR VALS VALLLD VALLLD, + "truncate", msg->ev_token, msg->ev_sequence, + "file handle", hans1, + "offset", msg_de->de_offset, + "length", msg_de->de_length); + break; + } + } + + /***** DESTROY EVENT *****/ + + else if (msg->ev_type == DM_EVENT_DESTROY) { + dm_destroy_event_t *msg_ds; + char attrname[DM_ATTR_NAME_SIZE + 1]; + u_char *copy; + u_int clen; + u_int i; + + msg_ds= DM_GET_VALUE(msg, ev_data, dm_destroy_event_t *); + hanp1 = DM_GET_VALUE(msg_ds, ds_handle, void *); + hlen1 = DM_GET_LEN (msg_ds, ds_handle); + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } else { + sprintf(hans1, "", hlen1); + } + if (msg_ds->ds_attrname.an_chars[0] != '\0') { + strncpy(attrname, (char *)msg_ds->ds_attrname.an_chars, sizeof(attrname)); + } else { + strcpy(attrname, ""); + } + printf(HDR VALS VALS, + "destroy", msg->ev_token, msg->ev_sequence, + "handle", hans1, + "attrname", attrname); + copy = DM_GET_VALUE(msg_ds, ds_attrcopy, u_char *); + clen = DM_GET_LEN (msg_ds, ds_attrcopy); + if (copy && clen) { + printf("\t%-15s ", "attrcopy"); + for (i = 0; i < clen; i++) { + printf("%.2x", copy[i]); + } + printf("\n"); + } else { + printf(VALS, "attrcopy", ""); + } + respond = 0; + } + + /***** MOUNT EVENT *****/ + + else if (msg->ev_type == DM_EVENT_MOUNT) { + printf(HDR, "mount", msg->ev_token, msg->ev_sequence); +#if !VERITAS_21 + msg_me = DM_GET_VALUE(msg, ev_data, dm_mount_event_t *); + print_one_mount_event(msg_me); +#else /* VERITAS_21 */ + msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *); + print_one_mount_event(msg_ne); +#endif /* VERITAS_21 */ + } + + /***** NAMESPACE EVENTS *****/ + + else { + char *type; + + msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *); + hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *); + hlen1 = DM_GET_LEN (msg_ne, ne_handle1); + hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *); + hlen2 = DM_GET_LEN (msg_ne, ne_handle2); + namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *); + nlen1 = DM_GET_LEN (msg_ne, ne_name1); + namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *); + nlen2 = DM_GET_LEN (msg_ne, ne_name2); + + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } + if (hanp2 && hlen2) { + hantoa(hanp2, hlen2, hans2); + } + if (namp1 && nlen1) { + strncpy(nams1, namp1, nlen1); + if (nlen1 != sizeof(nams1)) + nams1[nlen1] = '\0'; + } + if (namp2 && nlen2) { + strncpy(nams2, namp2, nlen2); + if (nlen2 != sizeof(nams2)) + nams2[nlen2] = '\0'; + } + + if (msg->ev_type == DM_EVENT_PREUNMOUNT || + msg->ev_type == DM_EVENT_UNMOUNT) { + if (msg_ne->ne_mode == 0) { + type = "NOFORCE"; +#if !VERITAS_21 + } else if (msg_ne->ne_mode == DM_UNMOUNT_FORCE) { +#else + } else if (msg_ne->ne_mode > 0) { +#endif + type = "FORCE"; + } else { + type = "UNKNOWN"; + pkt_error++; + } + } else if (msg->ev_type == DM_EVENT_CREATE || + msg->ev_type == DM_EVENT_POSTCREATE || + msg->ev_type == DM_EVENT_REMOVE || + msg->ev_type == DM_EVENT_POSTREMOVE) { + if (format_mode(msg_ne->ne_mode, &type)) { + pkt_error++; + } + } + + switch(msg->ev_type) { + + case DM_EVENT_PREUNMOUNT: + printf(HDR VALS VALS VALS, + "preunmount", msg->ev_token, msg->ev_sequence, + "fs handle", hans1, + "root dir", hans2, + "unmount mode", type); + break; + + case DM_EVENT_UNMOUNT: + printf(HDR VALS VALS VALD, + "unmount", msg->ev_token, msg->ev_sequence, + "fs handle", hans1, + "unmount mode", type, + "retcode", msg_ne->ne_retcode); + break; + + case DM_EVENT_NOSPACE: + printf(HDR VALS, + "nospace", msg->ev_token, msg->ev_sequence, + "fs handle", hans1); + response = DM_RESP_ABORT; + respcode = ENOSPC; + break; + + case DM_EVENT_DEBUT: /* not supported on SGI */ + printf(HDR VALS, + "debut", msg->ev_token, msg->ev_sequence, + "object", hans1); + break; + + case DM_EVENT_CREATE: + printf(HDR VALS VALS VALS, + "create", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "mode bits", type); + break; + + case DM_EVENT_POSTCREATE: + printf(HDR VALS VALS VALS VALS VALD, + "postcreate", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "new object", hans2, + "name", nams1, + "mode bits", type, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_REMOVE: + printf(HDR VALS VALS VALS, + "remove", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "mode bits", type); + break; + + case DM_EVENT_POSTREMOVE: + printf(HDR VALS VALS VALS VALD, + "postremove", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "mode bits", type, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_RENAME: + printf(HDR VALS VALS VALS VALS, + "rename", msg->ev_token, msg->ev_sequence, + "old parent", hans1, + "new parent", hans2, + "old name", nams1, + "new name", nams2); + break; + + case DM_EVENT_POSTRENAME: + printf(HDR VALS VALS VALS VALS VALD, + "postrename", msg->ev_token, msg->ev_sequence, + "old parent", hans1, + "new parent", hans2, + "old name", nams1, + "new name", nams2, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_SYMLINK: + printf(HDR VALS VALS VALS, + "symlink", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "contents", nams2); + break; + + case DM_EVENT_POSTSYMLINK: + printf(HDR VALS VALS VALS VALS VALD, + "postsymlink", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "new object", hans2, + "name", nams1, + "contents", nams2, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_LINK: + printf(HDR VALS VALS VALS, + "link", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "source", hans2, + "name", nams1); + break; + + case DM_EVENT_POSTLINK: + printf(HDR VALS VALS VALS VALD, + "postlink", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "source", hans2, + "name", nams1, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_ATTRIBUTE: + printf(HDR VALS, + "attribute", msg->ev_token, msg->ev_sequence, + "object", hans1); + respond = 0; + break; + + case DM_EVENT_CLOSE: /* not supported on SGI */ + printf(HDR VALS, + "close", msg->ev_token, msg->ev_sequence, + "object", hans1); + respond = 0; + break; + + default: + pkt_error++; + printf(HDR VALD, + "", msg->ev_token, msg->ev_sequence, + "ev_type", msg->ev_type); + if (msg->ev_token == DM_INVALID_TOKEN) + respond = 0; + break; + } + } + + /* + * Now respond to those messages which require a response + */ + if (respond) { + error = dm_respond_event(sid, msg->ev_token, response, respcode, 0, 0); + if (error) { + errno_msg("Can't respond to event"); + return error; + } + if (Sleep) { + err_msg("Sleeping for %d seconds!\n", Sleep); + sleep(Sleep); + } + } + + return 0; +} + + +/* + Convert a mode_t field into a printable string. + + Returns non-zero if the mode_t is invalid. The string is + returned in *ptr, whether there is an error or not. +*/ + +static int +format_mode( + mode_t mode, + char **ptr) +{ +static char modestr[100]; + char *typestr; + int error = 0; + + if (S_ISFIFO(mode)) typestr = "FIFO"; + else if(S_ISCHR (mode)) typestr = "Character Device"; + else if(S_ISBLK (mode)) typestr = "Block Device"; + else if(S_ISDIR (mode)) typestr = "Directory"; + else if(S_ISREG (mode)) typestr = "Regular File"; + else if(S_ISLNK (mode)) typestr = "Symbolic Link"; + else if(S_ISSOCK(mode)) typestr = "Socket"; + else { + typestr = ""; + error++; + } + + sprintf(modestr, "mode %06o: perm %c%c%c %c%c%c %c%c%c %c%c%c, type %s", + mode, + mode & S_ISUID ? 's':' ', + mode & S_ISGID ? 'g':' ', + mode & S_ISVTX ? 't':' ', + mode & S_IRUSR ? 'r':'-', + mode & S_IWUSR ? 'w':'-', + mode & S_IXUSR ? 'x':'-', + mode & S_IRGRP ? 'r':'-', + mode & S_IWGRP ? 'w':'-', + mode & S_IXGRP ? 'x':'-', + mode & S_IROTH ? 'r':'-', + mode & S_IWOTH ? 'w':'-', + mode & S_IXOTH ? 'x':'-', + typestr); + *ptr = modestr; + return(error); +} + + +static int +get_fs_handle( + char *fsname, + void **fs_hanpp, + size_t *fs_hlenp) +{ + char hans[HANDLE_STR]; + + if (dm_path_to_fshandle(fsname, fs_hanpp, fs_hlenp) == -1) { + errno_msg("Can't get filesystem handle"); + return 1; + } + if (Verbose) { + hantoa(*fs_hanpp, *fs_hlenp, hans); + err_msg("File system handle for %s: %s\n", fsname, hans); + } + return 0; +} + + +/* + Set the event disposition for this filesystem to include all valid + DMAPI events so that we receive all events for this filesystem. + Also set DM_EVENT_MOUNT disposition for the global handle. + It does not make sense to specify DM_EVENT_USER in the disposition + mask since a session is always unconditionally registered for these + events. + + Returns non-zero on error. +*/ + +static int +set_disposition( + dm_sessid_t sid, + void *fs_hanp, + size_t fs_hlen) +{ + dm_eventset_t eventlist; + + if (Verbose) { + err_msg("Setting event disposition to send all " + "events to this session\n"); + } + + /* DM_EVENT_MOUNT must be sent in a separate request using the global + handle. If we ever support more than one filesystem at a time, this + request should be moved out of this routine to a place where it is + issued just once. + */ + + DMEV_ZERO(eventlist); + DMEV_SET(DM_EVENT_MOUNT, eventlist); + + if (dm_set_disp(sid, DM_GLOBAL_HANP, DM_GLOBAL_HLEN, DM_NO_TOKEN, + &eventlist, DM_EVENT_MAX) == -1) { + errno_msg("Can't set event disposition for mount"); + return(1); + } + + DMEV_ZERO(eventlist); + + /* File system administration events. */ + + DMEV_SET(DM_EVENT_PREUNMOUNT, eventlist); + DMEV_SET(DM_EVENT_UNMOUNT, eventlist); + DMEV_SET(DM_EVENT_NOSPACE, eventlist); + + /* While DM_EVENT_DEBUT is optional, it appears that the spec always + lets it be specified in a dm_set_disp call; its just that the + event will never be seen on some platforms. + */ + + DMEV_SET(DM_EVENT_DEBUT, eventlist); + + + /* Namespace events. */ + + DMEV_SET(DM_EVENT_CREATE, eventlist); + DMEV_SET(DM_EVENT_POSTCREATE, eventlist); + DMEV_SET(DM_EVENT_REMOVE, eventlist); + DMEV_SET(DM_EVENT_POSTREMOVE, eventlist); + DMEV_SET(DM_EVENT_RENAME, eventlist); + DMEV_SET(DM_EVENT_POSTRENAME, eventlist); + DMEV_SET(DM_EVENT_LINK, eventlist); + DMEV_SET(DM_EVENT_POSTLINK, eventlist); + DMEV_SET(DM_EVENT_SYMLINK, eventlist); + DMEV_SET(DM_EVENT_POSTSYMLINK, eventlist); + + /* Managed region data events. */ + + DMEV_SET(DM_EVENT_READ, eventlist); + DMEV_SET(DM_EVENT_WRITE, eventlist); + DMEV_SET(DM_EVENT_TRUNCATE, eventlist); + + /* Metadata events. */ + + DMEV_SET(DM_EVENT_ATTRIBUTE, eventlist); +#if 0 +#if ! defined ( __sgi ) && ! defined ( VERITAS_21 ) + DMEV_SET(DM_EVENT_CANCEL, eventlist); /* not supported on SGI */ +#endif +#ifndef __sgi + DMEV_SET(DM_EVENT_CLOSE, eventlist); /* not supported on SGI */ +#endif +#endif + DMEV_SET(DM_EVENT_DESTROY, eventlist); + + /* Pseudo-events. */ + + /* DM_EVENT_USER - always enabled - causes EINVAL if specified */ + + if (dm_set_disp(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, + &eventlist, DM_EVENT_MAX) == -1) { + errno_msg("Can't set event disposition for filesystem"); + return(1); + } + return(0); +} + + +/* + Enable event generation on each valid filesystem-based DMAPI event + within the given file system. + + Returns non-zero on errors. +*/ + +static int +set_events( + dm_sessid_t sid, + void *fs_hanp, + size_t fs_hlen) +{ + dm_eventset_t eventlist; + + if (Verbose) { + err_msg("Setting event list to enable all events " + "for this file system\n"); + } + DMEV_ZERO(eventlist); + + /* File system administration events. */ + + /* DM_EVENT_MOUNT - always enabled on the global handle - causes + EINVAL if specified. + */ + DMEV_SET(DM_EVENT_PREUNMOUNT, eventlist); + DMEV_SET(DM_EVENT_UNMOUNT, eventlist); + DMEV_SET(DM_EVENT_NOSPACE, eventlist); + /* DM_EVENT_DEBUT - always enabled - causes EINVAL if specified. */ + + /* Namespace events. */ + + DMEV_SET(DM_EVENT_CREATE, eventlist); + DMEV_SET(DM_EVENT_POSTCREATE, eventlist); + DMEV_SET(DM_EVENT_REMOVE, eventlist); + DMEV_SET(DM_EVENT_POSTREMOVE, eventlist); + DMEV_SET(DM_EVENT_RENAME, eventlist); + DMEV_SET(DM_EVENT_POSTRENAME, eventlist); + DMEV_SET(DM_EVENT_LINK, eventlist); + DMEV_SET(DM_EVENT_POSTLINK, eventlist); + DMEV_SET(DM_EVENT_SYMLINK, eventlist); + DMEV_SET(DM_EVENT_POSTSYMLINK, eventlist); + + /* Managed region data events. These are not settable by + dm_set_eventlist on a filesystem basis. They are meant + to be set using dm_set_region on regular files only. + However, in the SGI implementation, they are filesystem-settable. + Since this is useful for testing purposes, do it. + */ + + /* DM_EVENT_READ */ + /* DM_EVENT_WRITE */ + /* DM_EVENT_TRUNCATE */ + + /* Metadata events. */ + + DMEV_SET(DM_EVENT_ATTRIBUTE, eventlist); +#if 0 +#if ! defined ( __sgi ) && ! defined ( VERITAS_21 ) + DMEV_SET(DM_EVENT_CANCEL, eventlist); /* not supported on SGI */ +#endif +#ifndef __sgi + DMEV_SET(DM_EVENT_CLOSE, eventlist); /* not supported on SGI */ +#endif +#endif + DMEV_SET(DM_EVENT_DESTROY, eventlist); + + /* Pseudo-events. */ + + /* DM_EVENT_USER - always enabled - causes EINVAL if specified */ + + if (dm_set_eventlist(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, + &eventlist, DM_EVENT_MAX) == -1) { + errno_msg("Can't set event list"); + return(1); + } + return(0); +} + + +/* + Disable monitoring for all events in the DMAPI for the given + file system. This is done before exiting so that future + operations won't hang waiting for their events to be handled. + + Returns non-zero on errors. +*/ + +static int +clear_events( + dm_sessid_t sid, + void *fs_hanp, + size_t fs_hlen) +{ + dm_eventset_t eventlist; + + if (Verbose) { + err_msg("Clearing event list to disable all events " + "for this filesystem\n"); + } + DMEV_ZERO(eventlist); + + if (dm_set_eventlist(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, + &eventlist, DM_EVENT_MAX) == -1) { + errno_msg("Can't clear event list"); + return(1); + } + return(0); +} + + +/* + * Respond to any events which haven't been handled yet. + * dm_getall_tokens provides a list of tokens for the outstanding events. + * dm_find_eventmsg uses the token to lookup the corresponding message. + * The message is passed to handle_message() for normal response processing. + */ +int +finish_responding( + dm_sessid_t sid) +{ + int error = 0; + u_int nbytes, ntokens = 0, ret_ntokens, i; + dm_token_t *tokenbuf = NULL; + size_t buflen, ret_buflen; + char *msgbuf = NULL; + dm_eventmsg_t *msg; + + if (Verbose) + err_msg("Responding to any outstanding delivered event messages\n"); + + /* + * Initial sizes for the token and message buffers + */ + ret_buflen = 16 * (sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + + HANDLE_LEN); + ret_ntokens = 16; + + /* + * The E2BIG dance... + * Take a guess at how large to make the buffer, starting with ret_ntokens. + * If the routine returns E2BIG, use the returned size and try again. + * If we're already using the returned size, double it and try again. + */ + do { + ntokens = (ntokens != ret_ntokens) ? ret_ntokens : ntokens*2; + nbytes = ntokens * (sizeof(dm_token_t) + sizeof(dm_vardata_t)); + tokenbuf = malloc(nbytes); + if (tokenbuf == NULL) { + err_msg("Can't malloc %d bytes for tokenbuf\n", nbytes); + error = 1; + goto out; + } + error = dm_getall_tokens(sid, ntokens, tokenbuf, &ret_ntokens); + } while (error && errno == E2BIG); + + if (error) { + errno_msg("Can't get all outstanding tokens"); + goto out; + } + + for (i = 0; i < ret_ntokens; i++) { + if (Verbose) + err_msg("Responding to outstanding event for token %d\n",(int)*tokenbuf); + + /* + * The E2BIG dance reprise... + */ + do { + buflen = (buflen != ret_buflen) ? ret_buflen : buflen * 2; + msgbuf = malloc(buflen); + if (msgbuf == NULL) { + err_msg("Can't malloc %d bytes for msgbuf\n", buflen); + error = 1; + goto out; + } + error = dm_find_eventmsg(sid, *tokenbuf, buflen, msgbuf, &ret_buflen); + } while (error && errno == E2BIG); + if (error) { + errno_msg("Can't find the event message for token %d", (int)*tokenbuf); + goto out; + } + + msg = (dm_eventmsg_t *) msgbuf; + while (msg != NULL) { + error = handle_message(sid, msg); + if (error) + goto out; + msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *); + } + + tokenbuf++; + } + + out: + if (tokenbuf) + free(tokenbuf); + if (msgbuf) + free(msgbuf); + return error; +} + + +/* + * Establish an exit handler since we run in an infinite loop + */ +int +establish_handler(void) +{ + struct sigaction act; + + /* + * Set up signals so that we can wait for spawned children + */ + act.sa_handler = exit_handler; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + + (void)sigaction(SIGHUP, &act, NULL); + (void)sigaction(SIGINT, &act, NULL); + (void)sigaction(SIGQUIT, &act, NULL); + (void)sigaction(SIGTERM, &act, NULL); + (void)sigaction(SIGUSR1, &act, NULL); + (void)sigaction(SIGUSR1, &act, NULL); + (void)sigaction(SIGUSR2, &act, NULL); + + return(0); +} + + +/* + * Exit gracefully + * + * Stop events from being generated for the given file system + * Respond to any events that were delivered but unanswered + * (the event loop may have been in the middle of taking care of the event) + * Try getting any undelivered events but don't block if none are there + * (the file system may have generated an event after we killed dm_get_events) + * Shutdown the session using the global "sid" variable. + */ +void +exit_handler(void) +{ + int error; + void *fs_hanp; + size_t fs_hlen; + + if (Verbose) + printf("\n"), + err_msg("Exiting...\n"); + + error = get_fs_handle(fsname, &fs_hanp, &fs_hlen); + + if (!error) { + error = clear_events(sid, fs_hanp, fs_hlen); + if (error) + /* just keep going */ ; + } + + error = finish_responding(sid); + if (error) + /* just keep going */ ; + + err_msg("Processing any undelivered event messages\n"); + event_loop(sid, 0 /*waitflag*/); + + err_msg("Shutting down the session\n"); + if (sid != NULL) { + error = dm_destroy_session(sid); + if (error == -1) { + errno_msg("Can't shut down session - use 'mrmean -kv' to clean up!"); + } + } + + exit(0); +} diff --git a/dmapi/src/suite1/cmd/print_fshandle.c b/dmapi/src/suite1/cmd/print_fshandle.c new file mode 100644 index 000000000..5bfab9967 --- /dev/null +++ b/dmapi/src/suite1/cmd/print_fshandle.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +/* Given a file pathname, print the filesystem handle and the uuid_t for + the filesystem that contains the file. +*/ + +#include +#ifdef linux +#else +#include +#include +#include +#endif + +#include +#include +#include +#include + +#include + + +static void +hantoa( + void *hanp, + size_t hlen, + char *handle_str) +{ + u_char *cp= (u_char *)hanp; + int i; + + for (i = 0;i < hlen; i++, handle_str += 2) + sprintf(handle_str, "%.2x", *cp++); + *handle_str = '\0'; +} + +int +main( + int argc, + char **argv) +{ +/* xfs_fsop_geom_t geom;*/ + char *uuid_str; + u_int status; + char *name; + int fd; + void *fshanp; + size_t fshlen; + char buffer[100]; + + if (argc != 2) { + fprintf(stderr, "usage: %s path\n", argv[0]); + exit(1); + } + (void)dm_init_service(&name); + + if (dm_path_to_fshandle(argv[1], &fshanp, &fshlen) != 0) { + fprintf(stderr, "dm_path_to_fshandle failed, %s\n", + strerror(errno)); + } + hantoa(fshanp, fshlen, buffer); + + if ((fd = open(argv[1], O_RDONLY)) < 0) { + fprintf(stderr, "Open of %s failed, %s\n", argv[1], + strerror(errno)); + exit(1); + } + +/* + syssgi(SGI_XFS_FSOPERATIONS, fd, XFS_FS_GEOMETRY, NULL, &geom); + + uuid_to_string(&geom.uuid, &uuid_str, &status); + + fprintf(stdout, "fshandle %s, uuid %s, %s\n", + buffer, uuid_str, argv[1]); +*/ + fprintf(stdout, "fshandle %s, %s\n", + buffer, argv[1]); +} diff --git a/dmapi/src/suite1/cmd/probe_hole.c b/dmapi/src/suite1/cmd/probe_hole.c new file mode 100644 index 000000000..4c3f3bc40 --- /dev/null +++ b/dmapi/src/suite1/cmd/probe_hole.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_probe_hole(). The +command line is: + + probe_hole [-o offset] [-l length] [-s sid] pathname + +where pathname is the name of a file, offset is the offset of the start of +the proposed punch, and length is the length of the punch. sid is the +session ID whose events you you are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-o offset] [-l length] " + "[-s sid] pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname = NULL; + dm_off_t offset = 0; + dm_size_t length = 0; + dm_off_t roffp; + dm_size_t rlenp; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "o:l:s:")) != EOF) { + switch (opt) { + case 'o': + offset = atol(optarg); + break; + case 'l': + length = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", pathname); + exit(1); + } + + if (dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length, + &roffp, &rlenp)) { + fprintf(stderr, "dm_probe_hole failed, %s\n", + strerror(errno)); + exit(1); + } + fprintf(stdout, "roffp is %lld, rlenp is %lld\n", roffp, rlenp); + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/punch_hole.c b/dmapi/src/suite1/cmd/punch_hole.c new file mode 100644 index 000000000..e1137ede5 --- /dev/null +++ b/dmapi/src/suite1/cmd/punch_hole.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_punch_hole(). The +command line is: + + punch_hole [-o offset] [-l length] [-s sid] pathname + +where pathname is the name of a file, offset is the offset of the start of +the punch, and length is the length of the punch. sid is the +session ID whose events you you are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-o offset] [-l length] " + "[-s sid] pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname = NULL; + dm_off_t offset = 0; + dm_size_t length = 0; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "o:l:s:")) != EOF) { + switch (opt) { + case 'o': + offset = atol(optarg); + break; + case 'l': + length = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", pathname); + exit(1); + } + + if (dm_punch_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length)) { + fprintf(stderr, "dm_punch_hole failed, %s\n", + strerror(errno)); + exit(1); + } + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/query_right.c b/dmapi/src/suite1/cmd/query_right.c new file mode 100644 index 000000000..7b1251a14 --- /dev/null +++ b/dmapi/src/suite1/cmd/query_right.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_query_right(). The +command line is: + + query_right [-F] [-s sid] token {pathname|handle} + +where +-F + when a pathname is specified, -F indicates that its filesystem handle + should be used rather than its file object handle. +sid + is the dm_sessid_t to use rather than the default test session. +token + is the dm_token_t to use. +{pathname|handle} + is either a handle, or is the pathname of a file whose handle is + to be used. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-F] [-s sid] token " + "{pathname|handle}\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token; + dm_right_t right; + char *object; + char *rightstr; + void *hanp; + size_t hlen; + int Fflag = 0; + int wflag = 0; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fs:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + token = atol(argv[optind++]); + object = argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file or filesystem's handle. */ + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle from %s\n", object); + exit(1); + } + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + if (dm_query_right(sid, hanp, hlen, token, &right)) { + fprintf(stderr, "dm_query_right failed, %s\n", + strerror(errno)); + return(1); + } + + fprintf(stderr, "right is %s\n", rt_value_to_name(right)); + + dm_handle_free(hanp, hlen); +} diff --git a/dmapi/src/suite1/cmd/randomize_file.c b/dmapi/src/suite1/cmd/randomize_file.c new file mode 100644 index 000000000..c99e382a5 --- /dev/null +++ b/dmapi/src/suite1/cmd/randomize_file.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#include +#include +#include +#include + +/* + This program reads the file specified on the command line and + produces a new file on stdout which contains the lines from the + input file scrambled into a random order. This is useful for + 'randomizing' a database to simulate the kind of I/O that will + occur when many records have been added and deleted over time. +*/ + +#define FIELD_WIDTH 21 + +static char buffer[4096]; + +int +main( + int argc, + char **argv) +{ + FILE *infile; + FILE *tmpfile; + char *path; + int line_count = 0; + int i; + int j; + + if (argc != 2) { + fprintf(stderr, "Usage: %s infile\n", argv[0]); + exit(1); + } + + /* Read through the input file and count how many lines are present. */ + + if ((infile = fopen(argv[1], "r")) == NULL) { + fprintf(stderr, "can't open %s\n", argv[1]); + exit(1); + } + for (;;) { + if (fgets(buffer, sizeof(buffer), infile) == NULL) { + if (!ferror(infile)) + break; + fprintf(stderr, "Error on infile\n"); + exit(1); + } + line_count++; + } + fprintf(stderr, "%d lines in input file\n", line_count); + + /* Create a temp file. Copy the input file to the temp file, + prepending a random number in the range + 0 <= X <= linecount-1 + to each line copied. + */ + + path = tmpnam(NULL); + if ((tmpfile = fopen(path, "w")) == NULL) { + fprintf(stderr, "error opening temp file %s\n", path); + exit(1); + } + rewind(infile); + srand48((long)getpid()); + + for (i = line_count - 1; i >= 0; i--) { + if (fgets(buffer, sizeof(buffer), infile) == NULL) { + if (!ferror(infile)) + break; + fprintf(stderr, "Error on infile\n"); + exit(1); + } + j = (int)(drand48() * (float)i); + fprintf(tmpfile, "%*d ", FIELD_WIDTH - 1, j); + fputs(buffer, tmpfile); + } + if (fclose(infile)) { + fprintf(stderr, "close of input file failed\n"); + exit(1); + } + if (fclose(tmpfile)) { + fprintf(stderr, "close of temp file %s failed\n", path); + exit(1); + } + fprintf(stderr, "random mapping complete\n"); + + /* Use the system sort routine to sort the file into order on the + first field, effectively randomizing the lines. + */ + + sprintf(buffer, "sort +0 -1 -o %s %s", path, path); + if (system(buffer)) { + fprintf(stderr, "sort call failed\n"); + exit(1); + } + fprintf(stderr, "sort complete\n"); + + /* Copy the temp file to stdout, removing the prepended field. */ + + if ((tmpfile = fopen(path, "rw")) == NULL) { + fprintf(stderr, "error reopening temp file %s\n", path); + exit(1); + } + + for (i = 0; i < line_count; i++) { + if (fgets(buffer, sizeof(buffer), tmpfile) == NULL) { + if (!ferror(tmpfile)) + break; + fprintf(stderr, "Error on tmpfile\n"); + exit(1); + } + if (fputs(buffer + FIELD_WIDTH, stdout) < 0) { + fprintf(stderr, "Error on outfile\n"); + exit(1); + } + } + if (unlink(path)) { + fprintf(stderr, "can't unlink %s\n", path); + exit(1); + } +} diff --git a/dmapi/src/suite1/cmd/release_right.c b/dmapi/src/suite1/cmd/release_right.c new file mode 100644 index 000000000..40849aa1f --- /dev/null +++ b/dmapi/src/suite1/cmd/release_right.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_release_right(). The +command line is: + + release_right {-F} [-s sid] token {pathname|handle} + +where: +-F + when a pathname is specified, -F indicates that its filesystem handle + should be used rather than its file object handle. +sid + is the dm_sessid_t to use rather than the default test session. +token + is the dm_token_t to use. +{pathname|handle} + is either a handle, or is the pathname of a file whose handle is + to be used. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-F] [-s sid] token {pathname|handle}\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token; + char *object; + void *hanp; + size_t hlen; + int Fflag = 0; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fs:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + token = atol(argv[optind++]); + object = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file or filesystem's handle. */ + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle from %s\n", object); + exit(1); + } + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + if (dm_release_right(sid, hanp, hlen, token)) { + fprintf(stderr, "dm_release_right failed, %s\n", + strerror(errno)); + return(1); + } + + dm_handle_free(hanp, hlen); +} diff --git a/dmapi/src/suite1/cmd/remove_dmattr.c b/dmapi/src/suite1/cmd/remove_dmattr.c new file mode 100644 index 000000000..163adbef9 --- /dev/null +++ b/dmapi/src/suite1/cmd/remove_dmattr.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_remove_dmattr(). The +command line is: + + remove_dmattr [-s sid] [-u] pathname attr + +where pathname is the name of a file, attr is the name of the DMAPI attribute, +and sid is the session ID whose attributes you are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-s sid] [-u] pathname attr\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname; + dm_attrname_t *attrnamep; + int setdtime = 0; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "s:u")) != EOF) { + switch (opt) { + case 's': + sid = atol(optarg); + break; + case 'u': + setdtime = 1; + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + pathname = argv[optind++]; + attrnamep = (dm_attrname_t *)argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", pathname); + exit(1); + } + + if (dm_remove_dmattr(sid, hanp, hlen, DM_NO_TOKEN, setdtime, + attrnamep)) { + fprintf(stderr, "dm_remove_dmattr failed, %s\n", + strerror(errno)); + exit(1); + } + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/request_right.c b/dmapi/src/suite1/cmd/request_right.c new file mode 100644 index 000000000..3859b38a9 --- /dev/null +++ b/dmapi/src/suite1/cmd/request_right.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_request_right(). The +command line is: + + request_right [-F] [-w] [-s sid] token {pathname|handle} right + +where +-F + when a pathname is specified, -F indicates that its filesystem handle + should be used rather than its file object handle. +-w + if specified, the DM_RR_WAIT flag will be used. +sid + is the dm_sessid_t to use rather than the default test session. +token + is the dm_token_t to use. +{pathname|handle} + is either a handle, or is the pathname of a file whose handle is + to be used. +right + is the dm_right_t to use. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-F] [-w] [-s sid] token " + "{pathname|handle} right\n", Progname); + fprintf(stderr, "possible rights are:\n"); + for (i = 0; i < rt_namecnt; i++) { + fprintf(stderr, "%s (%d)\n", rt_names[i].name, + rt_names[i].value); + } + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token; + dm_right_t right; + char *object; + char *rightstr; + void *hanp; + size_t hlen; + int Fflag = 0; + int wflag = 0; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fws:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 'w': + wflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 3 != argc) + usage(); + token = atol(argv[optind++]); + object = argv[optind++]; + rightstr = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file or filesystem's handle. */ + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle from %s\n", object); + exit(1); + } + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + if (rt_name_to_value(rightstr, &right)) { + fprintf(stderr, "invalid right %s\n", rightstr); + usage(); + } + + if (dm_request_right(sid, hanp, hlen, token, + (wflag ? DM_RR_WAIT : 0), right)) { + fprintf(stderr, "dm_request_right failed, %s\n", + strerror(errno)); + return(1); + } + + dm_handle_free(hanp, hlen); +} diff --git a/dmapi/src/suite1/cmd/respond_event.c b/dmapi/src/suite1/cmd/respond_event.c new file mode 100644 index 000000000..59447cfef --- /dev/null +++ b/dmapi/src/suite1/cmd/respond_event.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_respond_event(). The +command line is: + + respond_event sid token response reterror + +where sid is the session ID whose event you are responding to. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s sid token response reterror\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid; + char *name; + dm_token_t token; + dm_response_t response; + int reterror; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + if (argc != 5) + usage(); + + sid = atol(argv[1]); + token = atol(argv[2]); + response = atol(argv[3]); + reterror = atol(argv[4]); + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + + if (dm_respond_event(sid, token, response, reterror, 0, NULL)) { + fprintf(stderr, "dm_respond_event failed, %d/%s\n", + errno, strerror(errno)); + exit(1); + } + exit(0); +} diff --git a/dmapi/src/suite1/cmd/rwt.c b/dmapi/src/suite1/cmd/rwt.c new file mode 100644 index 000000000..429ffe2e7 --- /dev/null +++ b/dmapi/src/suite1/cmd/rwt.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test DMAPI by issuing read, write, and trunc calls to a +file. The command line is: + + rwt [-r|-w|-t] [-o offset] [-l length] pathname + +where: +-r + indicates that a read should be done (the default if none specified) +-w + indiates that a write should be done +-t + indicates that a truncate should be done, in which case the -l + parameter is ignored. +-o offset + offset at which to begin the read, write or truncate (default is 0). +-l length + the length in bytes to read or write (default is 1). +pathname + the file to be used by the test. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-r|-w|-t] [-o offset] [-l length] " + "pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *pathname = NULL; + off_t offset = 0; + size_t length = 1; + u_char ch = 'X'; + void *bufp = NULL; + off_t seek_off; + int rflag = 0; + int wflag = 0; + int tflag = 0; + int fd; + ssize_t rc; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "rwto:l:")) != EOF) { + switch (opt) { + case 'r': + rflag++; + break; + case 'w': + wflag++; + break; + case 't': + tflag++; + break; + case 'o': + offset = atol(optarg); + break; + case 'l': + length = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + if (rflag + wflag + tflag > 1) + usage(); + pathname = argv[optind]; + + if ((fd = open(pathname, O_RDWR)) < 0) { + fprintf(stderr, "open of %s failed, %s\n", pathname, + strerror(errno)); + exit(1); + } + if (length > 0) { + if ((bufp = malloc(length)) == NULL) { + fprintf(stderr, "malloc of %d bytes failed\n", length); + exit(1); + } + if (wflag) + memset(bufp, ch, length); + } + + if (!tflag) { + if ((seek_off = lseek(fd, offset, SEEK_SET)) < 0) { + fprintf(stderr, "seek failed, %s\n", strerror(errno)); + exit(1); + } + if (seek_off != offset) { + fprintf(stderr, "seeked to offset %d, actually " + "arrived at %d\n", offset, seek_off); + exit(1); + } + } + + if (wflag) { + if ((rc = write(fd, bufp, length)) < 0) { + fprintf(stderr, "write failed, %s\n", strerror(errno)); + exit(1); + } + if (rc != length) { + fprintf(stderr, "expected to write %d bytes, actually " + "wrote %d bytes\n", length, rc); + exit(1); + } + } else if (tflag) { + if (ftruncate(fd, offset) != 0) { + fprintf(stderr, "truncate failed, %s\n", + strerror(errno)); + exit(1); + } + } else { + if ((rc = read(fd, bufp, length)) < 0) { + fprintf(stderr, "read failed, %s\n", strerror(errno)); + exit(1); + } + if (rc != length) { + fprintf(stderr, "expected to read %d bytes, actually " + "read %d bytes\n", length, rc); + exit(1); + } + } + exit(0); +} diff --git a/dmapi/src/suite1/cmd/security_hole.c b/dmapi/src/suite1/cmd/security_hole.c new file mode 100644 index 000000000..1bfdbdd13 --- /dev/null +++ b/dmapi/src/suite1/cmd/security_hole.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include +#include +#include + +#ifdef linux +#include +#endif + +/* + To read unallocated disk blocks in a filesystem, do + cc -o test thisfile.c + ./test myfile + cat myfile +*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + +static char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-s size] pathname\n", Progname); + fprintf(stderr, "\t-s size\t\tsize of file (default 10,000,000 bytes)\n"); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *pathname = NULL; + off_t size = 10000000; + char buff[1]; + int method = F_RESVSP; + flock_t flock; + int opt; + int fd; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "s:")) != EOF) { + switch (opt) { + case 's': + size = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind]; + + /* Create the file and write one byte at a large offset to create a + big hole in the middle of the file. + */ + + if ((fd = open(pathname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) { + perror("open failed"); + exit(1); + } + if (lseek(fd, size, 0) < 0) { + perror("lseek failed"); + exit(1); + } + buff[0] = '\0'; + if (write(fd, buff, 1) != 1) { + perror("write failed"); + exit(1); + } + + /* Now fill in the hole with uninitialized blocks. */ + + flock.l_whence = 0; + flock.l_start = 0; + flock.l_len = size; + + if (fcntl(fd, method, &flock) < 0) { + perror("fcntl failed"); + exit(1); + } + printf("%s created\n", pathname); +} diff --git a/dmapi/src/suite1/cmd/security_hole2.c b/dmapi/src/suite1/cmd/security_hole2.c new file mode 100644 index 000000000..dac11d628 --- /dev/null +++ b/dmapi/src/suite1/cmd/security_hole2.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include +#include +#include + +/* + To read unallocated disk blocks in a filesystem, do + cc -o test thisfile.c + ./test myfile + cat myfile +*/ + +extern char *sys_errlist[]; +extern int optind; +extern char *optarg; + +static char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-s size] pathname\n", Progname); + fprintf(stderr, "\t-s size\t\tsize of file (default 10,000,000 bytes)\n"); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + char *pathname = NULL; + off_t size = 10000000; + char buff[1]; + int method = F_RESVSP; + flock_t flock; + int opt; + int fd; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "s:")) != EOF) { + switch (opt) { + case 's': + size = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind]; + + /* Create the file and write one byte at a large offset to create a + big hole in the middle of the file. + */ + + if ((fd = open(pathname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) { + perror("open failed"); + exit(1); + } + + /* First allocate uninitialized blocks. */ + + flock.l_whence = 0; + flock.l_start = 0; + flock.l_len = size; + + if (fcntl(fd, method, &flock) < 0) { + perror("fcntl failed"); + exit(1); + } + + /* Now seek out and write the byte. */ + + if (lseek(fd, size, 0) < 0) { + perror("lseek failed"); + exit(1); + } + buff[0] = '\0'; + if (write(fd, buff, 1) != 1) { + perror("write failed"); + exit(1); + } + printf("%s created\n", pathname); +} diff --git a/dmapi/src/suite1/cmd/set_disp.c b/dmapi/src/suite1/cmd/set_disp.c new file mode 100644 index 000000000..736414cea --- /dev/null +++ b/dmapi/src/suite1/cmd/set_disp.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_set_eventlist(). The +command line is: + + set_disp [-m max] [-s sid] [-t token] {pathname|handle} [event...] + set_disp [-m max] [-s sid] -G [DM_EVENT_MOUNT] + +where +{pathname|handle} + is the name of a file or handle whose filesystem is of interest. +-G + if the global handle should be used +max + is the value to use for the maxevent parameter of dm_set_disp(), +sid + is the dm_sessid_t to use rather than the default test session. +token + is the dm_token_t to use in place of DM_NO_TOKEN. +event + is zero or more events to set. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-m max] [-s sid] [-t token] " + "{pathname|handle} [event...]\n", Progname); + fprintf(stderr, "usage:\t%s [-m max] [-s sid] -G [DM_EVENT_MOUNT]\n", + Progname); + fprintf(stderr, "possible events are:\n"); + for (i = 0; i < ev_namecnt; i++) { + fprintf(stderr, "%s (%d)\n", ev_names[i].name, + ev_names[i].value); + } + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token = DM_NO_TOKEN; + u_int maxevent = DM_EVENT_MAX; + dm_eventset_t eventset; + void *fshanp; + size_t fshlen; + int Gflag = 0; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Gm:s:t:")) != EOF) { + switch (opt) { + case 'G': + Gflag++; + break; + case 'm': + maxevent = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case 't': + token = atol(optarg); + break; + case '?': + usage(); + } + } + if (Gflag && token != DM_NO_TOKEN) + usage(); + if (optind + (Gflag ? 0 : 1) > argc) + usage(); + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + DMEV_ZERO(eventset); + + /* Get the file or filesystem's handle. */ + + if (Gflag) { + fshanp = DM_GLOBAL_HANP; + fshlen = DM_GLOBAL_HLEN; + } else { + char *object; + void *hanp; + size_t hlen; + + object = argv[optind++]; + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle from %s\n", object); + exit(1); + } + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + } + + for (; optind < argc; optind++) { + dm_eventtype_t event; + + event = ev_name_to_value(argv[optind]); + if (event == DM_EVENT_INVALID) { + fprintf(stderr, "invalid event %s\n", argv[optind]); + usage(); + } + DMEV_SET(event, eventset); + } + + if (dm_set_disp(sid, fshanp, fshlen, token, &eventset, maxevent)) { + fprintf(stderr, "dm_set_disp failed, %s\n", + strerror(errno)); + exit(1); + } + + if (!Gflag) + dm_handle_free(fshanp, fshlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/set_dmattr.c b/dmapi/src/suite1/cmd/set_dmattr.c new file mode 100644 index 000000000..b510eb5fe --- /dev/null +++ b/dmapi/src/suite1/cmd/set_dmattr.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_set_dmattr(). The +command line is: + + set_dmattr [-b buflen] [-s sid] [-u] pathname attr value + +where pathname is the name of a file, buflen is the size of the buffer to use +in the call, attr is the name of the DMAPI attribute, -u is selected if +setdtime should be updated, and sid is the session ID whose attributes you +are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-b buflen] [-s sid] [-u] pathname " + "attr value\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname; + dm_attrname_t *attrnamep; + char *bufp; + size_t buflen; + int bflag = 0; + int setdtime = 0; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "b:s:u")) != EOF) { + switch (opt) { + case 'b': + bflag++; + buflen = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case 'u': + setdtime = 1; + break; + case '?': + usage(); + } + } + if (optind + 3 != argc) + usage(); + pathname = argv[optind++]; + attrnamep = (dm_attrname_t *)argv[optind++]; + bufp = argv[optind]; + if (!bflag) + buflen = strlen(bufp) + 1; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s, %s\n", + pathname, strerror(errno)); + exit(1); + } + + if (dm_set_dmattr(sid, hanp, hlen, DM_NO_TOKEN, attrnamep, setdtime, + buflen, bufp)) { + fprintf(stderr, "dm_set_dmattr failed, %s\n", + strerror(errno)); + exit(1); + } + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/set_eventlist.c b/dmapi/src/suite1/cmd/set_eventlist.c new file mode 100644 index 000000000..4300bb966 --- /dev/null +++ b/dmapi/src/suite1/cmd/set_eventlist.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_set_eventlist(). The +command line is: + + set_eventlist [-F] [-m max] [-s sid] [-t token] {pathname|handle} event [...] + +where: +{pathname|handle} + is either the pathname of a file or a handle. +max + is the value to use for the maxevent parameter of dm_set_eventlist(). +sid + is the dm_sessid_t value to use. +token + is the dm_token_t value to use (DM_NO_TOKEN is the default). +event + is one or more events to set. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-F] [-m max] [-s sid] " + "{pathname|handle} event [...]\n", Progname); + fprintf(stderr, "possible events are:\n"); + for (i = 0; i < ev_namecnt; i++) { + fprintf(stderr, "%s (%d)\n", ev_names[i].name, + ev_names[i].value); + } + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token = DM_NO_TOKEN; + char *object; + dm_eventset_t eventset; + void *hanp; + size_t hlen; + int Fflag = 0; + u_int maxevent = DM_EVENT_MAX; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fm:s:t:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 'm': + maxevent = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case 't': + token = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 > argc) + usage(); + object = argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + DMEV_ZERO(eventset); + + /* Get the file's handle or convert the external handle. */ + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for %s\n", object); + exit(1); + } + + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + for (; optind < argc; optind++) { + dm_eventtype_t event; + + event = ev_name_to_value(argv[optind]); + if (event == DM_EVENT_INVALID) { + fprintf(stderr, "invalid event %s\n", argv[optind]); + usage(); + } + DMEV_SET(event, eventset); + } + + if (dm_set_eventlist(sid, hanp, hlen, token, &eventset, maxevent)) { + fprintf(stderr, "dm_set_eventlist failed, %s\n", + strerror(errno)); + exit(1); + } + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/set_fileattr.c b/dmapi/src/suite1/cmd/set_fileattr.c new file mode 100644 index 000000000..f22e47eaa --- /dev/null +++ b/dmapi/src/suite1/cmd/set_fileattr.c @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include + +#ifdef linux +#include +#endif + + +extern int optind; +extern int opterr; +extern char *optarg; + +static char *Progname; + +#define MIN_HD_DATE 19800101 +#define MIN_HD_TMSTAMP 315554400 /* timestamp of 19800101 */ + +static int dayno, day_of_week; +static int leap_year; + +/* + * The following table is used for USA daylight savings time and + * gives the day number of the first day after the Sunday of the + * change. + */ +static struct { + int yrbgn; + int daylb; + int dayle; +} daytab[] = { + 1987, 96, 303, /* new legislation - 1st Sun in April */ + 1976, 119, 303, /* normal Last Sun in Apr - last Sun in Oct */ + 1975, 58, 303, /* 1975: Last Sun in Feb - last Sun in Oct */ + 1974, 5, 333, /* 1974: Jan 6 - last Sun. in Nov */ + 1970, 119, 303, /* start GMT */ +}; +#define DAYTABSIZE (sizeof(daytab)/sizeof(daytab[0])) + + +/****************************************************************************** +* NAME +* dysize +* +* DESCRIPTION +* Return number of days in year y. +* +******************************************************************************/ + +int +dysize(int y) +{ + int temp; + temp = (y%4)==0; + if (temp) { + if ( (y%100)==0) + temp = ( (y%400) != 0); + } + return(365+temp); +} + +/****************************************************************************** +* NAME +* sunday +* +* DESCRIPTION +* sunday - return sunday daynumber. Argument d is the day number of the +* first Sunday on or before the special day. Variables leap_year, dayno, +* and day_of_week must have been set before sunday is called. +* +* RETURN VALUE +* The sunday daynumber. +* +******************************************************************************/ + +static int +sunday(int d) +{ + if(d >= 58) + d += leap_year; + return(d - (d - dayno + day_of_week + 700) % 7); +} + + +extern long +cnvdate(int mon, int mday, int year, int hour, int min, int sec) +{ + int t, i; + int daylbegin, daylend; + int ly_correction; /* Leap Year Correction */ + int dl_correction; /* Daylight Savings Time Correction */ + long s; + static int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; + + days[2] = 28; + + /* Verify Input Parameters. */ + + /* Set year. */ + + if( year < 0) { + return(-1); + } + if( year < 100) { + if (year < 70) year += 2000; + else year += 1900; + } + if (year < 1970) { + return(-1); + } + if( year>2099 ) { + return(-1); + } + + if (dysize(year) == 366) { + leap_year = 1; + days[2]++; + } else + leap_year = 0; + /* + * Set ly_correction = number of leap year days from 1/1/1970 to + * 1/1/year. + */ + ly_correction = ((year-1969) / 4); + + /* Check Month */ + + if( (mon < 1) || (mon > 12)) { + return(-1); + } + + /* Check Day */ + + if ( (mday < 1) || (mday > days[mon]) ) { + return(-1); + } + + /* Check Time */ + + if( (hour<0) || (hour>23)) { + return(-1); + } + if( (min<0) || (min>59)) { + return(-1); + } + if( (sec<0) || (sec>59)) { + return(-1); + } + + /* Calculate Correction for Daylight Savings Time (U.S.) */ + + dayno = mday-1; + for (t=0; tDAYTABSIZE) + return(-1); + } + daylbegin = daytab[i].daylb; + daylend = daytab[i].dayle; + + daylbegin = sunday(daylbegin); + daylend = sunday(daylend); + if(daylight && + (dayno>daylbegin || (dayno==daylbegin && hour>=2)) && + (dayno 12) + return(0); + day = l % 100; + + /* Note: invalid day numbers are caught in cnvdate */ + + ptr+=8; + + l = strtol(ptr, &last_char, 10); + if (l < 0 || l>235959 || *last_char != '\0') + return(0); + hr = l / 10000; + if (hr > 23) + return(0); + l = l % 10000; + mn = l / 100; + if (mn > 59) + return(0); + sec = l % 100; + if (sec > 59) + return(0); + + /* Get timestamp. */ + + (void)tzset(); + if ((*timestamp = cnvdate(mon, day, yr, hr, mn, sec)) < 0) { + return(0); + } + + return(1); +} + + +/* Cracks dates in the form: NNs, NNm, NNh, or NNd which are interpreted + as NN seconds, minutes, hours, or days prior to the current time, + respectively. +*/ + +static int +get_relative_date( + char *ptr, + time_t *timestamp) +{ + int l; + char *last_char; + + if (!isdigit(*ptr)) + return(0); + l = strtol (ptr, &last_char, 10); + (void) time(timestamp); + if (strcmp(last_char, "s") == 0) + /* do nothing */; + else if (strcmp(last_char, "m") == 0) + l = l * 60; + else if (strcmp(last_char, "h") == 0) + l = l * 60 * 60; + else if (strcmp(last_char, "d") == 0) + l = l * 60 * 60 * 24; + else + return(0); + *timestamp -= l; + if (*timestamp < MIN_HD_TMSTAMP) + return(0); + return(1); +} + + +static void +usage(void) +{ + fprintf(stderr, "Usage: %s [-M mode] [-u uid] [-g gid] [-a atime] \\\n" + "\t[-m mtime] [-c ctime] [-d dtime] [-S size] [-s sid] pathname\n", + Progname); + fprintf(stderr, "\nDates can either be absolute:\n"); + fprintf(stderr, "\t\tYYYYMMDD or YYYYMMDDHHMMSS\n"); + fprintf(stderr, "or relative (prior to) the current time:\n"); + fprintf(stderr, "\tNNs (seconds), NNm (minutes), NNh (hours), " + " or NNd (days)\n"); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char buffer[500]; + void *hanp; + size_t hlen; + dm_fileattr_t fileattr; + u_int mask = 0; + char *pathname; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + opterr = 0; + while ((opt = getopt(argc, argv, "M:u:g:a:m:c:d:S:s:")) != EOF) { + switch (opt) { + case 'M': + mask |= DM_AT_MODE; + fileattr.fa_mode = strtol (optarg, NULL, 8); + break; + case 'u': + mask |= DM_AT_UID; + fileattr.fa_uid = atol(optarg); + break; + case 'g': + mask |= DM_AT_GID; + fileattr.fa_gid = atol(optarg); + break; + case 'a': + mask |= DM_AT_ATIME; + if (get_absolute_date(optarg, &fileattr.FA_ATIME)) + break; + if (get_relative_date(optarg, &fileattr.FA_ATIME)) + break; + usage(); + case 'm': + mask |= DM_AT_MTIME; + if (get_absolute_date(optarg, &fileattr.FA_MTIME)) + break; + if (get_relative_date(optarg, &fileattr.FA_MTIME)) + break; + usage(); + case 'c': + mask |= DM_AT_CTIME; + if (get_absolute_date(optarg, &fileattr.FA_CTIME)) + break; + if (get_relative_date(optarg, &fileattr.FA_CTIME)) + break; + usage(); + case 'd': + mask |= DM_AT_DTIME; + if (get_absolute_date(optarg, &fileattr.FA_DTIME)) + break; + if (get_relative_date(optarg, &fileattr.FA_DTIME)) + break; + usage(); + case 'S': + mask |= DM_AT_SIZE; + fileattr.fa_size = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) { + usage(); + } + pathname = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "dm_path_to_handle failed, %s\n", + strerror(errno)); + exit(1); + } + + if (dm_set_fileattr(sid, hanp, hlen, DM_NO_TOKEN, mask, &fileattr)) { + fprintf(stderr, "dm_set_fileattr failed, %s\n", + strerror(errno)); + exit(1); + } +} diff --git a/dmapi/src/suite1/cmd/struct_test.c b/dmapi/src/suite1/cmd/struct_test.c new file mode 100644 index 000000000..9453d21ea --- /dev/null +++ b/dmapi/src/suite1/cmd/struct_test.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include +#include + +#ifdef linux +#include +#else +#include +#endif + +/* The purpose of this test is to make sure that each field in each structure + defined in dmi.h is properly aligned so that there is no dead space, and + that the sizes and offsets of those fields remain constant no matter what + mode the program is compiled with, i.e. -32, -n32 or -64. + + Run the program with no parameters. If everything is correct, no message + will start with the word "ERROR:". Compile and run the test in each of + the three mods and diff the outputs. They must all be identical. + + Note: this test cannot detect the addition of new structures to dmi.h, so + it will have to periodically be compared with dmi.h manually to ensure that + all the structures are still being validated! +*/ + +#define S_START(struct_name) { offset = 0; s_name = #struct_name; } + +#define S_NEXT(struct_name, field_name) \ +{ \ + struct_name X; \ + \ + f_name = #field_name; \ + printf("field %s.%s offset is %d\n", s_name, f_name, offset); \ + if (offsetof(struct_name, field_name) != offset) { \ + printf("ERROR: field %s should be %d\n", \ + #struct_name "." #field_name, \ + offsetof(struct_name, field_name)); \ + } \ + offset = offsetof(struct_name, field_name) + sizeof(X.field_name); \ +} + +#define S_END(struct_name) \ +{ \ + printf("struct %s size is %d\n", s_name, offset); \ + if (sizeof(struct_name) != offset) { \ + printf("ERROR: struct %s should be %d\n", \ + s_name, sizeof(struct_name)); \ + } \ +} + + + +int main( + int argc, + char **argv) +{ + char *s_name = NULL; + char *f_name = NULL; + int offset = 0; + + + S_START(dm_vardata_t); + S_NEXT(dm_vardata_t, vd_offset); + S_NEXT(dm_vardata_t, vd_length); + S_END(dm_vardata_t); + + + S_START(dm_attrname_t); + S_NEXT(dm_attrname_t, an_chars); + S_END(dm_attrname_t); + + + S_START(dm_attrlist_t); + S_NEXT(dm_attrlist_t, _link); + S_NEXT(dm_attrlist_t, al_name); + S_NEXT(dm_attrlist_t, al_data); + S_END(dm_attrlist_t); + + + S_START(dm_dispinfo_t); + S_NEXT(dm_dispinfo_t, _link); + S_NEXT(dm_dispinfo_t, di_pad1); + S_NEXT(dm_dispinfo_t, di_fshandle); + S_NEXT(dm_dispinfo_t, di_eventset); + S_END(dm_dispinfo_t); + + + S_START(dm_eventmsg_t); + S_NEXT(dm_eventmsg_t, _link); + S_NEXT(dm_eventmsg_t, ev_type); + S_NEXT(dm_eventmsg_t, ev_token); + S_NEXT(dm_eventmsg_t, ev_sequence); + S_NEXT(dm_eventmsg_t, ev_data); + S_END(dm_eventmsg_t); + + + S_START(dm_cancel_event_t); + S_NEXT(dm_cancel_event_t, ce_sequence); + S_NEXT(dm_cancel_event_t, ce_token); + S_END(dm_cancel_event_t); + + + S_START(dm_data_event_t); + S_NEXT(dm_data_event_t, de_handle); + S_NEXT(dm_data_event_t, de_offset); + S_NEXT(dm_data_event_t, de_length); + S_END(dm_data_event_t); + + + S_START(dm_destroy_event_t); + S_NEXT(dm_destroy_event_t, ds_handle); + S_NEXT(dm_destroy_event_t, ds_attrname); + S_NEXT(dm_destroy_event_t, ds_attrcopy); + S_END(dm_destroy_event_t); + + + S_START(dm_mount_event_t); + S_NEXT(dm_mount_event_t, me_mode); + S_NEXT(dm_mount_event_t, me_handle1); + S_NEXT(dm_mount_event_t, me_handle2); + S_NEXT(dm_mount_event_t, me_name1); + S_NEXT(dm_mount_event_t, me_name2); + S_NEXT(dm_mount_event_t, me_roothandle); + S_END(dm_mount_event_t); + + + S_START(dm_namesp_event_t); + S_NEXT(dm_namesp_event_t, ne_mode); + S_NEXT(dm_namesp_event_t, ne_handle1); + S_NEXT(dm_namesp_event_t, ne_handle2); + S_NEXT(dm_namesp_event_t, ne_name1); + S_NEXT(dm_namesp_event_t, ne_name2); + S_NEXT(dm_namesp_event_t, ne_retcode); + S_END(dm_namesp_event_t); + + + S_START(dm_extent_t); + S_NEXT(dm_extent_t, ex_type); + S_NEXT(dm_extent_t, ex_pad1); + S_NEXT(dm_extent_t, ex_offset); + S_NEXT(dm_extent_t, ex_length); + S_END(dm_extent_t); + + + S_START(dm_fileattr_t); + S_NEXT(dm_fileattr_t, fa_mode); + S_NEXT(dm_fileattr_t, fa_uid); + S_NEXT(dm_fileattr_t, fa_gid); + S_NEXT(dm_fileattr_t, fa_atime); + S_NEXT(dm_fileattr_t, fa_mtime); + S_NEXT(dm_fileattr_t, fa_ctime); + S_NEXT(dm_fileattr_t, fa_dtime); + S_NEXT(dm_fileattr_t, fa_pad1); + S_NEXT(dm_fileattr_t, fa_size); + S_END(dm_fileattr_t); + + + S_START(dm_inherit_t); + S_NEXT(dm_inherit_t, ih_name); + S_NEXT(dm_inherit_t, ih_filetype); + S_END(dm_inherit_t); + + + S_START(dm_region_t); + S_NEXT(dm_region_t, rg_offset); + S_NEXT(dm_region_t, rg_size); + S_NEXT(dm_region_t, rg_flags); + S_NEXT(dm_region_t, rg_pad1); + S_END(dm_region_t); + + + S_START(dm_stat_t); + S_NEXT(dm_stat_t, _link); + S_NEXT(dm_stat_t, dt_handle); + S_NEXT(dm_stat_t, dt_compname); + S_NEXT(dm_stat_t, dt_nevents); + S_NEXT(dm_stat_t, dt_emask); + S_NEXT(dm_stat_t, dt_pers); + S_NEXT(dm_stat_t, dt_pmanreg); + S_NEXT(dm_stat_t, dt_dtime); + S_NEXT(dm_stat_t, dt_change); + S_NEXT(dm_stat_t, dt_pad1); + + S_NEXT(dm_stat_t, dt_dev); + S_NEXT(dm_stat_t, dt_ino); + S_NEXT(dm_stat_t, dt_mode); + S_NEXT(dm_stat_t, dt_nlink); + S_NEXT(dm_stat_t, dt_uid); + S_NEXT(dm_stat_t, dt_gid); + S_NEXT(dm_stat_t, dt_rdev); + S_NEXT(dm_stat_t, dt_pad2); + S_NEXT(dm_stat_t, dt_size); + S_NEXT(dm_stat_t, dt_atime); + S_NEXT(dm_stat_t, dt_mtime); + S_NEXT(dm_stat_t, dt_ctime); + S_NEXT(dm_stat_t, dt_blksize); + S_NEXT(dm_stat_t, dt_blocks); + + S_NEXT(dm_stat_t, dt_pad3); + S_NEXT(dm_stat_t, dt_fstype); + + S_NEXT(dm_stat_t, dt_xfs_igen); + S_NEXT(dm_stat_t, dt_xfs_xflags); + S_NEXT(dm_stat_t, dt_xfs_extsize); + S_NEXT(dm_stat_t, dt_xfs_extents); + S_NEXT(dm_stat_t, dt_xfs_aextents); + S_NEXT(dm_stat_t, dt_xfs_dmstate); + S_END(dm_stat_t); + + + S_START(dm_xstat_t); + S_NEXT(dm_xstat_t, dx_statinfo); + S_NEXT(dm_xstat_t, dx_attrdata); + S_END(dm_xstat_t); +} diff --git a/dmapi/src/suite1/cmd/sync_by_handle.c b/dmapi/src/suite1/cmd/sync_by_handle.c new file mode 100644 index 000000000..3a248b97d --- /dev/null +++ b/dmapi/src/suite1/cmd/sync_by_handle.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_sync_by_handle(). The +command line is: + + sync_by_handle [-s sid] pathname + +where: +'sid' is the session ID to use for the call. +'pathname' is the name of the file to be sync'd. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-s sid] pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname = NULL; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "s:")) != EOF) { + switch (opt) { + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", pathname); + exit(1); + } + + if (dm_sync_by_handle(sid, hanp, hlen, DM_NO_TOKEN)) { + fprintf(stderr, "dm_sync_by_handle failed, %s\n", + strerror(errno)); + exit(1); + } + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite1/cmd/test_assumption.c b/dmapi/src/suite1/cmd/test_assumption.c new file mode 100644 index 000000000..a92fd3307 --- /dev/null +++ b/dmapi/src/suite1/cmd/test_assumption.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include +#include +#include + +#include + +/* + Test that the new session ID is correctly returned to the caller on + dm_create_session when the oldsid parameter is not DM_NO_SESSION. + + Test to make sure that DM_NO_TOKEN does not work if the session ID + is invalid. + + Both are needed so that session assumption works correctly. The + test creates a session, queries the session, assumes the session, + then attempts to check the event list of the old session ID while + using DM_NO_TOKEN. + + The only parameter is the pathname of a DMAPI filesystem. If it is + working correctly, you should get the error message: + + SUCCESS! + + Any message containing the word FAILURE indicates a problem. +*/ + +char *Progname; +dm_sessid_t sid = DM_NO_SESSION; /* session ID of original session */ +dm_sessid_t newsid = DM_NO_SESSION; /* session ID after session resumed */ +dm_eventset_t eventlist; + +int +main( + int argc, + char **argv) +{ + char buffer[DM_SESSION_INFO_LEN]; + void *hanp; + size_t hlen; + u_int nelem; + size_t rlen; + + Progname = argv[0]; + + if (argc != 2) { + fprintf(stderr, "usage:\t%s filesystem\n", Progname); + exit(1); + } + + /* Initialize the DMAPI interface and obtain a session ID, then verify + that the filesystem supports DMAPI. + */ + + if (setup_dmapi(&sid)) + exit(1); + + if (dm_path_to_handle(argv[1], &hanp, &hlen)) { + perror("FAILURE: can't get handle for filesystem"); + exit(1); + } + + /* Query the session just to make sure things are working okay. */ + + if (dm_query_session(sid, sizeof(buffer), buffer, &rlen)) { + errno_msg("FAILURE: can't query the original session ID %d", + sid); + exit(1); + } + fprintf(stdout, "Initial session ID: %d\n", sid); + fprintf(stdout, "Initial session message length: '%d'\n", rlen); + if (rlen > 0) { + fprintf(stdout, "Initial session message: '%s'\n", buffer); + } + + /* Now try to assume the session. */ + + if (dm_create_session(sid, "this is a new message", &newsid)) { + fprintf(stderr, "FAILURE: can't assume session %d\n", sid); + exit(1); + } + + /* Now query the new session. */ + + if (dm_query_session(newsid, sizeof(buffer), buffer, &rlen)) { + errno_msg("FAILURE: can't query the assumed session ID %d", + newsid); + exit(1); + } + fprintf(stdout, "Assumed session ID: %d\n", newsid); + fprintf(stdout, "Assumed session message length: '%d'\n", rlen); + if (rlen > 0) { + fprintf(stdout, "Assumed session message: '%s'\n", buffer); + } + + /* Get rid of the new session as we are done with it. */ + + if (dm_destroy_session(newsid)) { + fprintf(stderr, "FAILURE: Can't shut down assumed session %d\n", + newsid); + exit(1); + } + + /* Now verify that DM_NO_TOKEN will not work with the old session ID, + which is now invalid. + */ + + DMEV_ZERO(eventlist); + + if (dm_get_eventlist(sid, hanp, hlen, DM_NO_TOKEN, DM_EVENT_MAX, + &eventlist, &nelem) == 0) { + fprintf(stderr, "FAILURE: dm_get_eventlist() worked when it " + "should have failed!\n"); + } +#ifdef VERITAS_21 + if (errno != ESRCH) { +#else + if (errno != EINVAL) { +#endif + errno_msg("FAILURE: unexpected errno"); + exit(1); + } + fprintf(stdout, "SUCCESS!\n"); +} diff --git a/dmapi/src/suite1/cmd/upgrade_right.c b/dmapi/src/suite1/cmd/upgrade_right.c new file mode 100644 index 000000000..375d8f7ca --- /dev/null +++ b/dmapi/src/suite1/cmd/upgrade_right.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_upgrade_right(). The +command line is: + + upgrade_right {-F} [-s sid] token {pathname|handle} + +where: +-F + when a pathname is specified, -F indicates that its filesystem handle + should be used rather than its file object handle. +sid + is the dm_sessid_t to use rather than the default test session. +token + is the dm_token_t to use. +{pathname|handle} + is either a handle, or is the pathname of a file whose handle is + to be used. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-F] [-s sid] token {pathname|handle}\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token; + char *object; + void *hanp; + size_t hlen; + int Fflag = 0; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Fs:")) != EOF) { + switch (opt) { + case 'F': + Fflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + token = atol(argv[optind++]); + object = argv[optind]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file or filesystem's handle. */ + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle from %s\n", object); + exit(1); + } + if (Fflag) { + void *fshanp; + size_t fshlen; + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, "can't get filesystem handle from %s\n", + object); + exit(1); + } + dm_handle_free(hanp, hlen); + hanp = fshanp; + hlen = fshlen; + } + + if (dm_upgrade_right(sid, hanp, hlen, token)) { + fprintf(stderr, "dm_upgrade_right failed, %s\n", + strerror(errno)); + return(1); + } + + dm_handle_free(hanp, hlen); +} diff --git a/dmapi/src/suite1/function_coverage b/dmapi/src/suite1/function_coverage new file mode 100644 index 000000000..99956ee27 --- /dev/null +++ b/dmapi/src/suite1/function_coverage @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +/* functions for which there is a test program. */ + +dm_downgrade_right( +dm_fd_to_handle( +dm_get_allocinfo( +dm_get_config_events( +dm_get_dmattr( +dm_get_eventlist( +dm_get_events( +dm_get_fileattr( +dm_get_mountinfo( +dm_get_region( +dm_getall_disp( +dm_getall_dmattr( +dm_handle_cmp( +dm_handle_free( +dm_handle_hash( +dm_handle_is_valid( +dm_handle_to_fshandle( +dm_handle_to_fsid( +dm_handle_to_igen( +dm_handle_to_ino( +dm_handle_to_path( +dm_init_service( +dm_make_handle( +dm_make_fshandle( +dm_path_to_fshandle( +dm_path_to_handle( +dm_obj_ref_hold( +dm_obj_ref_query( +dm_obj_ref_rele( +dm_pending( +dm_probe_hole( +dm_punch_hole( +dm_read_invis( +dm_release_right( +dm_request_right( +dm_remove_dmattr( +dm_respond_event( +dm_set_disp( +dm_set_dmattr( +dm_set_eventlist( +dm_set_fileattr( +dm_set_region( +dm_set_return_on_destroy( +dm_sync_by_handle( +dm_upgrade_right( +dm_write_invis( + + +/* Functions which don't yet have a specific test program. */ + +dm_create_session( +dm_create_userevent( +dm_destroy_session( +dm_find_eventmsg( +dm_get_bulkattr( +dm_get_config( +dm_get_dirattrs( +dm_getall_sessions( +dm_getall_tokens( +dm_init_attrloc( +dm_move_event( +dm_query_session( +dm_send_msg( + +/* Non-standard SGI additions to the DMAPI interface. */ + +dm_get_dioinfo diff --git a/dmapi/src/suite2/DMAPI_aliases b/dmapi/src/suite2/DMAPI_aliases new file mode 100644 index 000000000..f8fb420b4 --- /dev/null +++ b/dmapi/src/suite2/DMAPI_aliases @@ -0,0 +1,147 @@ +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +#--------------------------------------------------------------------------- +# CONFIGURATION SECTION: +# Configure this script by changing the variables in this section. +# Please change ONLY this section! +#--------------------------------------------------------------------------- + +# Base directory: +base_dir="~jayw/test" + +# Primary username: +p_user="jayw" + +# Path to the mountpoint of the test filesystem: +m_main="/dmitest" + +# m_main concatenated with d_name == the full test directory path +# +# EXAMPLE: If m_main is "/dmitest", and the test directory +# is "/dmitest/test", set this to "/test" +# +d_name="/test" + +# Path to the mountpoint of the nfs2 test filesystem: +m_nfs2="/dmiv2" + +# Path to the mountpoint of the nfs3 test filesystem: +m_nfs3="/dmiv3" + +# Path to the mountpoint of the realtime test filesystem: +m_rt="/dmf" +# Path to the realtime test directory: +d_rt="$m_rt/kcm" + +#-------------------------------------------------------------------- +# END OF CONFIGURATION SECTION: +# No changes should be made past this point! Please change only +# the above shell variables to configure this script. +#-------------------------------------------------------------------- + +# Path to the "bindir" directory: +bin="$base_dir/bindir" + +# Path to the "generic file" (a copy of ls): +ls_path="$bin/ls_to_copy" + +# Path to the main test directory: +d_main="$m_main$d_name" + +# Path to the nfs2 test directory: +d_nfs2="$m_nfs2$d_name" + +# Path to the nfs3 test directory: +d_nfs3="$m_nfs2$d_name" + +#--------------------------------------------------------------------------- +# Tests that run without a daemon +#--------------------------------------------------------------------------- + +# Automated C programs to test DMAPI functions +alias do_dmattr="$bin/test_dmattr $ls_path $tdir" +alias do_eventlist="$bin/test_eventlist $ls_path $tdir" +alias do_fileattr="$bin/test_fileattr $ls_path $tdir" +alias do_hole="$bin/test_hole $ls_path $tdir" +alias do_invis="$bin/test_invis $ls_path $tdir" +alias do_region="$bin/test_region $ls_path $tdir" +alias do_efault="$bin/test_efault $ls_path $tdir" +alias do_rights="$bin/test_rights $ls_path $tdir" + +# Verbose versions of the above +alias dov_dmattr="$bin/test_dmattr -v $ls_path $tdir" +alias dov_eventlist="$bin/test_eventlist -v $ls_path $tdir" +alias dov_fileattr="$bin/test_fileattr -v $ls_path $tdir" +alias dov_hole="$bin/test_hole -v $ls_path $tdir" +alias dov_invis="$bin/test_invis -v $ls_path $tdir" +alias dov_region="$bin/test_region -v $ls_path $tdir" +alias dov_efault="$bin/efault -v $ls_path $tdir" +alias dov_rights="$bin/test_rights -v $ls_path $tdir" + +# Scripts to test dm_get_allocinfo +alias do_allocinfo_1="$bin/test_allocinfo_1 $bin $tdir" +alias do_allocinfo_2="$bin/test_allocinfo_2 $bin $tdir" + +#------------------------------------------------------------------------------------------------- +# Tests that load a DMAPI daemon and examine the generated events +#------------------------------------------------------------------------------------------------- + +# Standard battery of tests: +alias do_standard="$bin/run_test -u $p_user -f standard.dat $bin $tdir $mdir" +alias do_standard_nfs2="$bin/run_test -u $p_user -F nfs2 -M $m_nfs2 -R $tdir -f standard_nfs.dat $bin $d_nfs2 $mdir" +alias do_standard_nfs3="$bin/run_test -u $p_user -F nfs3 -M $m_nfs3 -R $tdir -f standard_nfs.dat $bin $d_nfs3 $mdir" + +# Some other, more specific tests: +alias do_main="$bin/run_test -u $p_user $bin $tdir $mdir" +alias do_nfs2="$bin/run_test -u $p_user -F nfs2 -M $m_nfs2 -R $tdir -f nfs.dat $bin $d_nfs2 $mdir" +alias do_nfs3="$bin/run_test -u $p_user -F nfs3 -M $m_nfs3 -R $tdir -f nfs.dat $bin $d_nfs3 $mdir" + +alias do_pending="$bin/run_test -u $p_user -f pending.dat $bin $tdir $mdir" +alias do_pending_nfs2="$bin/run_test -u $p_user -F nfs2 -M $m_nfs2 -R $tdir -f pending_nfs.dat $bin $d_nfs2 $mdir" +alias do_pending_nfs3="$bin/run_test -u $p_user -F nfs3 -M $m_nfs3 -R $tdir -f pending_nfs.dat $bin $d_nfs3 $mdir" + +alias do_failure="$bin/run_test -u $p_user -f fail.dat $bin $tdir $mdir" +alias do_failure_nfs2="$bin/run_test -u $p_user -F nfs2 -M $m_nfs2 -R $tdir -f fail.dat $bin $d_nfs2 $mdir" +alias do_failure_nfs3="$bin/run_test -u $p_user -F nfs3 -M $m_nfs3 -R $tdir -f fail.dat $bin $d_nfs3 $mdir" + +# Realtime test: +alias do_realtime="$bin/run_test -u $p_user -f realtime.dat $bin $m_rt $d_rt" + +# Small event queue test: Set dm_max_queued to about 5 or so before running! +alias do_smallq="$bin/run_test -u $p_user -s 2 -f smallq.dat $bin $tdir $mdir" + +#------------------------------------------------------------------------------------------------- +# Additional tools (these are NOT tests): +#------------------------------------------------------------------------------------------------- + +alias check_for_daemon="ps -el | grep daemon" +alias do_daemon="$bin/dm_test_daemon $mdir" diff --git a/dmapi/src/suite2/README b/dmapi/src/suite2/README new file mode 100644 index 000000000..c3fdf4066 --- /dev/null +++ b/dmapi/src/suite2/README @@ -0,0 +1,633 @@ +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + + + DMAPI Test Suite + Informational File + ------------------ + +I) Getting Started + + A) Extracting from DMAPI_test.cpio + + 1) Create a new directory for storing the tests. We will refer to + this as the "base" directory. The base directory can be + located anywhere; it does NOT need to be in a DMAPI filesystem. + + 2) Move the archive file DMAPI_test.cpio to the base directory + and execute the following command to extract from the archive: + + cpio -icvd < DMAPI_test.cpio + + 3) There should now be several files and subdirectories in the base + directory, including the file "file_list". Read this file for a + complete listing of which files should be present in which + directories. Compare "file_list" with the output of "ls -Rpl" + to be sure that you have the necessary files. + + 4) The base directory contains the files and programs that are of + immediate use for testing. The "bindir" subdirectory contains + the test programs and datafiles. The "lib" and "src" subdirectories + contain C libraries and source code for the C programs. + + B) Checking the Existence and Version of DMAPI + + The program check_dmapi can verify that you have the correct + version of DMAPI installed. NOTE: it can only be run as root. + Execute this command (from the "base" directory): + + bindir/check_dmapi + + It should report that you have a current version of DMAPI. If it + does not, it will also suggest which components of your DMAPI are + not current, and where to find a patch to update them. + + C) Configuration + + 1) Creating the Test Directories + + a) The Test Filesystem + + Mount a DMAPI filesystem, or use an existing one. + This filesystem's mount info MUST be listed in /etc/fstab. + + Write down the path to this filesystem's mountpoint, and label + it as "m_main" for future use. + + b) The Main Test Directory + + Create a new directory in the "m_main" filesystem. + + Write down the path to this directory. Note ONLY the part + that comes AFTER "m_main". Label this as "d_name". + + EXAMPLE: You have a DMAPI filesystem /dmi_main + You name the test directory /dmi_main/test_dir + "m_main" is /dmi_main + "d_name" is /test_dir + + c) The Cross-NFS Test Directories + + For NFS tests, all you must do is create two empty directories + (one for nfs2, one for nfs3). They do NOT need to be in a + DMAPI filesystem. + + Your main test directory will be mounted across NFS, into these + two directories. Normally, the tests will do this automatically. + However, if you need to do this mount manually, the command + would look like this example: + + mount -t nfs2 localhost:/dmi_main /dmi_nfs2 + + Write down the paths to these nfs2 and nfs3 test directories. + Label them "m_nfs2" and "m_nfs3" respectively. + + c) The Realtime Test Filesystem and Directory + + If you wish to test realtime i/o, you'll need a filesystem + mounted with a realtime partition, and a directory in that + filesystem. + + Label the path to the filesystem mountpoint as "m_rt". + Label the path to the test directory as "d_rt". + + 2) Configuring menu_test + + The Korn-shell script named menu_test is an interface to the + other test programs. At the beginning of the script, there + is a "configuration section", in which is sets several variables + for use in the rest of the script. + + Open menu_test in any text editor and change the following + variable assignments in the configuration section: + + a) base_dir: + Set this to the pathname of your "base" directory + (where you un-archived "DMAPI_test.cpio"). + + b) p_user: + Tests that do not run as root will run as this "primary" user. + Set this to any username. + + c) m_main: + The mountpoint of the main test filesystem. + Set this to the value of "m_main" that you wrote down above. + + d) d_name: + m_main concatenated with d_name is the main test directory path. + Set this to the value for "d_name" that you wrote down above. + + e) m_nfs2: + The mountpoint of the nfs2 test filesystem. + Set this to the value of "m_nfs2" that you wrote down above. + + f) m_nfs2: + The mountpoint of the nfs3 test filesystem. + Set this to the value of "m_nfs3" that you wrote down above. + + g) m_rt: + The mountpoint of the realtime test filesystem. + Set this to the value of "m_rt" that you wrote down above. + + h) d_rt: + The path to the realtime test directory. + Set this to the value of "d_rt" that you wrote down above. + + 3) Configuring "DMAPI_aliases" + + This is an optional alternative to the menu interface. It runs + as a Korn shell "dot" script and creates an alias to each test. + It was made for those who wish to run tests directly from the + command line. + + DMAPI_aliases has exactly the same configuration section as + menu_test. If you wish to use DMAPI_aliases, make the same + changes to its configuration section. + +II) Running the Tests + + A) Using "menu_test" to run tests + + 1) You must be superuser, using the Korn shell, to run menu_test. + You also must have adjusted the variables in menu_test's + "configuration section", as was explained above. + + 2) menu_test is (surprise!) menu based. Choose options by entering + their numbers. + + 3) The names of the menu options explain which DMAPI functions + or DMAPI events are being tested. Some of the options, labeled + accordingly, run more than one test programs. + + 4) See section SECTION# for a list of the test scripts and programs, + and a brief explanation of each script or program's function. + + B) Using "DMAPI_aliases" to run tests + + 1) NOTE: The aliases in DMAPI_aliases are meant to be used by + those who are familiar with the test programs and wish to run + them more directly. [Designer's note: I included the alias + file more out of nostalgia than necessity.] + + 2) You should be superuser, using the Korn shell, to run DMAPI_aliases. + You also must have adjusted the variables in DMAPI_aliases's + "configuration section", as was explained above. + + 3) DMAPI_aliases should be invoked as a Korn shell "dot" script: + + . ./DMAPI_aliases + + It sets an alias for each test program; each alias begins with + the characters "do_" and is followed by some appropriate name. + Read DMAPI_aliases, or execute "alias | grep do", to + + 4) "Verbose mode" + In the menu of function tests, one of the options is an on/off + toggle of "verbose mode". When verbose mode is on, the function + tests will print semi-explanatory output. Verbose mode affects + only the function tests (this does include check_dmapi). + + 5) "Pausing after each command" + In the menu of event tests, one of the options is a toggle of + "pausing after each command". When this is on, the event tests + will pause for a carriage return after running each command. + This affects only the event tests. + + C) Running tests directly + + 1) For the VERY adventurous, all the tests in the "bindir" directory + can be run directly from the command line. Only some of the files + in "bindir" are test scripts/programs. Read section III for a list + of function tests and section IV for a list of run_test (.dat) + testfiles. + + 2) Running a test program without parameters will produce a list of + correct options. (The exception to this is check_dmapi, which + normally has no parameters. check_dmapi takes only one option, + [-v] for verbose output.) + + 3) It is suggested that you read a program's source before running + it directly. (The source of the C programs is included in the + "src" directory.) Specifically, in each source file, an initial + comment explains the program's options/parameters in detail. + +III) DMAPI Function tests: + + This section offers a terse description of the DMAPI function tests. + For those tests written in C, the source code is given in the "src" + directory. The ksh scripts can, of course, be read directly. + In all cases except check_dmapi, running the program without + parameters will produce a list of correct options. + + A) check_dmapi + Written in: C + Test of: presence (and correct version) of DMAPI library and kernel. + Options: [-v] flag for verbose output. + + B) test_dmattr + Written in: C + Test of: dm_get_dmattr, dm_set_dmattr, dm_remove_dmattr. + + C) test_efault + Written in: C + Test of: various bad function calls that should generate EFAULT, + according to the DMAPI specification. + + D) test_eventlist + Written in: C + Test of: dm_get_eventlist, dm_set_eventlist. + + E) test_fileattr + Written in: C + Test of: dm_get_fileattr, dm_set_fileattr, + dm_get_dirattrs, dm_get_bulkattr. + + F) test_hole + Written in: C + Test of: dm_probe_hole, dm_punch_hole. + + G) test_invis + Written in: C + Test of: dm_read_invis, dm_write_invis. + + H) test_region + Written in: C + Test of: dm_get_region, dm_set,region. + + I) test_rights + Written in: C + Test of: various bad function calls that should generate EACCES, + and other conditions pertaining to DMAPI rights. + + J) test_allocinfo_1 + Written in: ksh + Test of: dm_get_allocinfo. + + K) test_allocinfo_2 + Written in: ksh + Test of: dm_get_allocinfo. + +IV) DMAPI Event tests and the "run_test" ksh script + + A) How to use the "run_test" script + + 1) A quick description of run_test's behavior: + run_test invokes a DMAPI daemon (as a ksh coprocess). It then + proceeds in a loop, in which it reads a command from a "testfile", + executes that command, reads a description of expected events from + the testfile, and compares the expected events with the actual + events, as returned by the DMAPI daemon. + + 2) You must be superuser, using the Korn shell, to execute run_test. + + 3) Executing run_test without parameters will produce a list of + correct options. For a much more in-depth explanation of the + options to run_test, read its own initial comment. + + B) The existing .dat testfiles + + 1) fail.dat + Tests the events from: a user trying to access files owned + by someone else (in this case, root). + + 2) main.dat + Tests the events from: events getting DM_RESP_ABORT, dm_send_msg(), + invisible i/o, and direct i/o. + + 3) nfs.dat + Tests the events from: events getting DM_RESP_ABORT over nfs, + EAGAIN over nfs. + + 4) pending.dat + Tests the events from: running dm_pending() while trying to + do standard i/o. + + 5) pending_nfs.dat + Tests the events from: running dm_pending() while trying to + do standard i/o over NFS + + 6) realtime.dat + Tests the events from: Invisible, direct, and standard i/o + on realtime files in a realtime filesystem. + + 7) smallq.dat + Tests the events from: Slow i/o due to a small event queue. + + 8) standard.dat + Tests the events from: various kinds of standard i/o, + memory-mapped i/o and remounting the filesystem. + + 9) standard_nfs.dat + Tests the events from: various kinds of standard i/o, over NFS. + + C) How to write new ".dat" testfiles + + 1) Overview + + A testfile contains a complete description of a DMAPI event test. + Testfiles are divided into sections: the first two contain + test initialization, while the remaining sections each contain ONE + command, followed by a list of expected events. + + The following is a description of testfile syntax. If you wish to + fully understand testfile syntax, PLEASE examine the existing + testfiles and the "run_test" script. + + 2) Event information variables + + a) From the daemon, "run_test" gets information about DMAPI events. + This information is stored in event information variables. + + b) NOTE: event information variables are not persistent. + After "run_test" has compared the expected and actual events + for a command, and before it executes the next command, it + unsets the values of all these variables. + + c) Most of these variables are arrays, indexed by the number of + the event (starting with 0). For example, if the initial event + is a read event, then we have "event[0]" set to "read", and + "file_handle[0]" set to the handle of whatever file was read. + + d) "event_count" is a special variable. It holds the number of + events that were generated by the most recent command. + + e) These are all the event information variables: + + contents event event_count fs_handle handle length + offset media_designator mode mountpoint_handle + mountpoint_path msg_str name new_name new_parent + parent_handle ret_code root_handle sequence token + tries_left unmount_mode + + f) PLEASE examine the run_test script to see which variables + are set by which events. (The scheme corresponds, roughly, + to the "Event Types" section of the DMAPI specification.) + + 3) Testfile section 1: List of required files + + a) A testfile's first section is a list of the files it requires. + If these files are not present in the "bindir" directory, + "run_test" will abort the test and inform the user of which + files are missing. + + b) Each line of this section may contain ANY NUMBER of filenames. + + c) Lines beginning with // will be treated as comments. The + entirety of such lines will be ignored. + + d) The last line of this section should begin with three hyphens + --- Other characters on that line will be ignored. + + 4) Testfile section 2: Initialization commands + + a) A testfile's second section consists of a list of commands. + "run_test" will execute these commands before starting the + DMAPI daemon. Any necessary initialization should be done + here. + + b) Each line of this section should be ONE shell command. + + c) Lines beginning with // will be treated as comments. + The entirety of such lines will be ignored. + + d) The last line of this section should begin with three hyphens + "---" Other characters on that line will be ignored. + + 5) Testfile sections 3 and on: Individual tests + + a) The remaining sections of a testfile consist of a single + shell command, followed by descriptions of events that should + be generated by the command. + + b) Comments + + 1) Comments are valid ONLY before the command. + + 2) Lines beginning with // will be treated as comments. + The entirety of such lines will be ignored. + + 3) Lines beginning with @@ will be treated as "print" comments. + Such lines will not be parsed, but they will be printed to + standard output during the test. This is useful for + describing what each test does. + + c) Valid grammar for the command itself + + 1) Standard command syntax: + This should be ONE shell command, on a line by itself. + + 2) Alternate command syntax: + A) run_as_root: + If the test is preceded by the metacommand "run_as_root" + (on a line by itself) then the command will be run as + root rather than as "p_user". The command should still + be one command on a line by itself. + + B) run_without_test: + If the test is preceded by the metacommand + "run_without_test" (on a line by itself), then ALL + subsequent lines in the section will be executed as + commands, and NO testing will be performed. Note that + the commands will be executed as root. This is useful + for re-initialization sections during a test. + NOTE: A testfile cannot end with a "run_without_test" + section. The last section must contain a test. + + d) Valid grammar for the "expected events" lines + + 1) [variable_name] [value] + This specifies that the variable [variable_name] should be + set to [value]. + + 2) [variable_name_1] matches [variable_name_2] + This specifies that both variables should be set to + the same value. A list of valid variables + + 3) [variable_name] store_in [string] + This specifies that the contents of [variable_name] + should be stored in a variable named [string]. + The variable [string] can then be referenced as a + variable in later tests. + + EXAMPLE: if two commands deal with the file "foobar", + you might want to check that they both use the same handle. + In the first section, write + "handle[0] store_in old_handle_0" + In the second section, write + "old_handle_0 matches handle[0]" + + 4) failure + This specifies that the command is expected to fail + (return some non-zero exit status). If "failure" + is not specified, the command is expected to succeed. + + e) The last line of these sections should begin with three + hyphens "---". Other characters on that line will be ignored. + + 6) Sending messages to the DMAPI daemon + + a) Overview + Normally, run_test only reads from the DMAPI daemon, and never + sends messages back. However, sometimes we need the daemon to + execute some function or change its behavior in some way. This + is accomplished by calling "send_msg" as a command in the + testfile. The test daemon has been coded to respond to the + following user events generated by send_msg: + + b) unfriendly_X + Replace X here with an integer, as in "send_msg unfriendly_6". + This causes the daemon to respond to all messages (other than + user events) with DM_RESP_ABORT instead of DM_RESP_CONTINUE, + and with errno X. If the message is just "unfriendly", the + default errno is EBADMSG. + + c) friendly + This returns the test_daemon to normal operation after it + was set to be "unfriendly". + + d) countdown_X_Y + Replace X and Y with integers, as in "send_msg countdown_6_8". + This causes the daemon to respond to the next X messages (other + than user events) with DM_RESP_ABORT instead of DM_RESP_CONTINUE, + and with errno Y. If the message is just "countdown", the + default count is 5 and the default errno is EAGAIN. + + e) pending_X + Replace X here with an integer, as in "send_msg pending_4". + This causes the daemon to call dm_pending() rather than + responding to the next X messages. If the message is just + "pending", the default count is 1. After the count reaches + zero, the messages will be responded to. + + f) reset_fs + This message MUST be sent after remounting the test filesystem. + It causes the daemon to re-register for all events. + + g) over + This message is sent by run_test itself, and should not be + sent in a testfile. "send_msg over" is called after each + command is executed, as an indicator that the batch of events + from that command is complete. When run_test sees a user + event with the data "over", it knows to stop reading events + and move on to the next command. + + 7) Other "helper functions" for testfiles + + a) ctf (create test files) + purpose: creates 20 copies of "bindir/ls_to_copy". + parameters: location of "bindir", location of target directory. + written in: ksh + + b) crttf (create realtime test files) + purpose: creates 10 realtime files. + parameters: location of "bindir", location of target directory. + written in: ksh + + c) stf (setup test files) + purpose: set dm attributes and managed regions on target files. + parameters: location of "bindir", pathnames of target files. + written in: ksh + + d) fcntl + purpose: do fcntl() syscall + parameters: see "usage" by running without parameters. + written in: C (source not included) + + e) open_test + purpose: do open() syscall + parameters: see "usage" by running without parameters. + written in: C + + f) rd + purpose: do read() syscall + parameters: see "usage" by running without parameters. + written in: C (source not included) + + g) new_wf + purpose: do write() syscall (new version of wf) + parameters: see "usage" by running without parameters. + written in: C (source not included) + + h) wf + purpose: do write() syscall + parameters: see "usage" by running without parameters. + written in: C (source not included) + + i) truncate + purpose: truncate a file + parameters: see "usage" by running without parameters. + written in: C (source not included) + + j) read_invis + purpose: do dm_read_invis() + parameters: see "usage" by running without parameters. + written in: C + + k) write_invis + purpose: do dm_write_invis(). + parameters: see "usage" by running without parameters. + written in: C + + l) set_region + purpose: do dm_set_region() + parameters: see "usage" by running without parameters. + written in: C + + m) set_return_on_destroy + purpose: do dm_set_return_on_destroy() + parameters: see "usage" by running without parameters. + written in: C + + n) ctest.c + purpose: test memory mapping used by cc during compilation + (really a helper file, not a helper function) + + o) mmap_cp + purpose: test memory mapping by using it to copy a file + parameters: source pathname, destination pathname + written in: C (source not included) + + p) dump_allocinfo + purpose: test dm_get_allocinfo by using it to dump + a list of file extents, much like to xfs_bmap. + parameters: see "usage" by running without parameters + written in: C + + q) mm_fill + purpose: fill a filesystem, using memory-mapped i/o + parameters: pathname of target file + written in: C + + r) make_holey + purpose: create a hole-filled file, using wf + parameters: path to "bindir", pathname of target file, + count of how many holes should be created + written in: ksh diff --git a/dmapi/src/suite2/README_for_check_dmapi b/dmapi/src/suite2/README_for_check_dmapi new file mode 100644 index 000000000..e32cda061 --- /dev/null +++ b/dmapi/src/suite2/README_for_check_dmapi @@ -0,0 +1,60 @@ +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +### README for check_dmapi ### + +check_dmapi tests the version of DMAPI library & kernel code. + +command line: check_dmapi [-v] +(v is a verbose-output flag) + +Functionality: + +1) Ensures that the user is running as root, using getuid(). + +2) Tries to stat() /usr/include/sys/dmi.h to verify its + presence and its size. + +3) Verifies the presence of the DMAPI kernel, using a + direct call to dmi(). The call is invalid, so it should + return EINVAL if the kernel code is in place, ENOPKG if not. + +4) Determines the status of the kernel (if it is present) using + a direct call to dmi(). The call is invalid, and uses an opcode + not present in the old kernel. So ENOSYS means old kernel; + EINVAL means new kernel. + +5) Determines the status of the library by calling dm_init_service(). + If this fails, libraries are missing. In the old library, this call + did not change its "name" parameter, but in the new library it does. + Same name means old library; changed name means new library. + +6) Outputs its findings. diff --git a/dmapi/src/suite2/bindir/crttf b/dmapi/src/suite2/bindir/crttf new file mode 100755 index 000000000..766661cc0 --- /dev/null +++ b/dmapi/src/suite2/bindir/crttf @@ -0,0 +1,43 @@ +#!/bin/ksh + +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +if [[ $# != 2 ]] +then print -u2 "USAGE: ${0##*/} bindir testdir" + exit 2 +fi + +for i in 0 1 2 3 4 5 6 7 8 9 + do + $1/new_wf -l 32768 -b 4096 -R $2/realtime.$i + done + diff --git a/dmapi/src/suite2/bindir/ctf b/dmapi/src/suite2/bindir/ctf new file mode 100755 index 000000000..a375b1483 --- /dev/null +++ b/dmapi/src/suite2/bindir/ctf @@ -0,0 +1,44 @@ +#!/bin/ksh + +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +if [[ $# != 2 ]] +then print -u2 "USAGE: ${0##*/} bindir testdir" + exit 2 +fi + +for i in 0 1 2 3 4 5 6 7 8 9 + do + cp $1/ls_to_copy $2/ls"$i" + cp $1/ls_to_copy $2/ll"$i" + done + diff --git a/dmapi/src/suite2/bindir/make_holey b/dmapi/src/suite2/bindir/make_holey new file mode 100755 index 000000000..42dd08733 --- /dev/null +++ b/dmapi/src/suite2/bindir/make_holey @@ -0,0 +1,57 @@ +#!/bin/ksh + +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +if [[ $# != 3 ]] +then print "usage: ${0##*/} bindir target_file count" + exit 1 +fi + +typeset -i offset +typeset -i length +typeset -i count + +RANDOM=$SECONDS +offset=0 +length=$RANDOM +count=$3 + +while (( count > 0 )) +do + print "Count: $count" + $1/wf -l $length -L $offset -b 512 $2 + (( offset = RANDOM * 512 + offset + length )) + (( length = RANDOM )) + (( count = count - 1 )) +done + + diff --git a/dmapi/src/suite2/bindir/run_test b/dmapi/src/suite2/bindir/run_test new file mode 100755 index 000000000..6b592f559 --- /dev/null +++ b/dmapi/src/suite2/bindir/run_test @@ -0,0 +1,552 @@ +#!/bin/ksh + +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +#-----------------------------------------------------------------# +# run_test: a ksh script for testing the DMAPI. +# +# USAGE: run_test [-p] [-x] [-u user] +# [-F fs_type -M fs_mtpt -R "real" directory] +# [-f datafile] [-s sleeptime] +# bindir testdir fsdir +# +# p: Causes pausing after every test (not just ones with errors). +# +# x: Prints an execution trace as the script runs. +# +# user: Most tests don't need root access, so they will be run +# under this username. +# +# (NOTE: the following three must be used together) +# +# fs_type: For NFS tests; the type of filesystem (ie nfs2, nfs3). +# +# fs_mtpt: For NFS tests, the path to the mount of your +# "real" filesystem. +# (ie, "mount -t nfs2 localhost:/dmitest $fs_mtpt") +# +# "real" directory: For NFS tests, the path to the "real" test directory. +# +# datafile: The name of the file which contains the tests to run. +# +# sleeptime: time, in seconds, for the daemon to sleep after +# responding to an event. (Useful for testing small +# outstanding-events queues.) +# +# bindir: The path to the directory that holds dm_test_daemon, send_msg, +# the datafile, and any other files required by the datafile. +# +# testdir: The path to the test directory. All DMAPI testing +# occurs here -- this is where the tests will actually +# be run. (For NFS tests, this will be an NFS mount +# of the "real" directory.) +# +# fsdir: The path name of the test filesystem. The daemon will start +# using this path, and the mount and unmount of the DMAPI +# filesystem will be done here. (Even for NFS tests, this +# should still be the same test filesystem.) +# +#-----------------------------------------------------------------# + +# For most reads, we'll want spaces to be the field separators. +IFS=" " + +typeset -i fail_flag +typeset -i pause_flag +typeset -i sleeptime + +# To run tests that don't require root access, we'll change to +# a user specified by lname. +lname=$LOGNAME + +# Set the default external files to use. +datafile=main.dat +sleeptime=0 + +unset fs_type fs_mtpt +real_dir=set_me_later + +# Parse the command-line options +while getopts :pxu:F:M:R:f:b:s: option +do case $option in + p) pause_flag=1;; + x) set -x;; + u) lname=$OPTARG;; + F) fs_type=$OPTARG;; + M) fs_mtpt=$OPTARG;; + R) real_dir=$OPTARG;; + f) datafile=$OPTARG;; + b) bindir=$OPTARG;; + s) sleeptime=$OPTARG;; + :) print -u2 "${0##*/}: $OPTARG requires a value" + exit 2;; + \?) print -nu2 "USAGE: ${0##*/} [-p] [-x] [-u user] " + print -nu2 "[-F fs type -M mountpoint directory -R \"real\" directory] " + print -u2 "[-s sleeptime] [-f datafile] bindir testdir fsdir" + exit 2;; + esac +done + +# Shift out the examined options, then check that we have +# exactly three arguments left: (the paths to the "bindir", +# the test directory, and the filesystem). +shift OPTIND-1 +if [[ $# != 3 ]] +then print -nu2 "USAGE: ${0##*/} [-p] [-x] [-u user] " + print -nu2 "[-F fs type -M mountpoint directory -R \"real\" directory] " + print -u2 "[-s sleeptime] [-f datafile] bindir testdir fsdir" + exit 2 +fi + +# For NFS tests, $2 will be an NFS mount of the test directory; +# real_dir should be the test directory's actual path. +# Otherwise, real_dir should just be $2. +if [[ $real_dir = set_me_later ]] +then real_dir=$2 +fi + +# Check bindir for the existence of our three critical external files. +error_count=0 +for i in dm_test_daemon send_msg $datafile +do + if [[ ! ( -r "$1/$i" ) ]] + then if ((error_count==0)) + then print "Aborting: the directory $1/ is missing critical files:" + fi + print "$1/$i" + (( error_count = error_count + 1 )) + fi +done +if (( error_count > 0 )) +then exit 1 +fi + +# Open the datafile on file descriptor 3 +exec 3< $1/$datafile + +# Read datafile and determine what files it needs from bindir; +# then, check for the existence of these files. +error_count=0 +while read -u3 file_list +do case $file_list in + ---*) break;; + //*) continue;; + *) for i in $file_list + do if [[ ! ( -r "$1/$i" ) ]] + then if ((error_count==0)) + then print "The directory $1/ is missing these files:" + fi + print "$1/$i" + (( error_count = error_count + 1 )) + fi + done;; + esac +done +if (( error_count > 0 )) + then exit 1 +fi + +# Run initialization stuff without daemon. +while read -u3 cmd +do case $cmd in + //*) continue;; + ---*) break;; + *) eval "$cmd";; + esac +done + +# If we're testing over nfs, remount the filesystem to clear the cache. +case $fs_type in + nfs2) print "Clearing nfs2 cache by remounting filesystem..." + eval "umount $fs_mtpt" + eval "mount -t nfs2 localhost:$3 $fs_mtpt";; + nfs3) print "Clearing nfs3 cache by remounting filesystem..." + eval "umount $fs_mtpt" + eval "mount -t nfs3 localhost:$3 $fs_mtpt";; + *) if [[ $fs_type != "" ]] + then print "ERROR: $fs_type not a known or testable filesystem type" + fi;; +esac + + +# Check with the user before starting up daemon +print "\n** Using testfile ${datafile##*/} **" +print "** Using userid $lname for tests not requiring root access **" +print "Press enter to begin, or enter q or n to abort..." +read go +case "$go" in + n|N|q|Q) exit 1;; + *);; +esac + +# Now, the user will need ownership of the test directory +# ($2, not $real_dir, since real_dir is accessed only as root). +eval "chown $lname $2" + +# Now it's time to begin running the daemon as a coprocess. +# The daemon will use a : as its internal field separator. +IFS=":" +if (($sleeptime > 0)) then + $1/dm_test_daemon -s $sleeptime $3 |& +else + $1/dm_test_daemon $3 |& +fi + +#Keep track of the coprocess id... "$!" may change. +coproc=$! + +# Initialize the count of errors +error_count=0; + +# dm_test_daemon starts with a spurious line feed. +read -p junk + +# Finally, we've reached the actual loop to read in the testfile. +while true +do + clear + while read -u3 cmd + do + case $cmd in + run_without_test) + while read -u3 cmd + do case $cmd in + ---*) clear; continue 2;; + //*) continue;; + @@*) cmd=${cmd#@@*} + print "!! ${cmd# *}" + continue;; + *) eval $cmd;; + esac + done;; + run_as_root) + read -u3 cmd + root_flag=1 + break;; + //*) continue;; + @@*) cmd=${cmd#@@*} + print "!! ${cmd# *}" + continue;; + *) root_flag=0 + break;; + esac + done + if (( $root_flag == 1 )) + then print "Command to execute (as root):\n\n $cmd\n" + eval "$cmd" + else print "Command to execute:\n\n $cmd\n" + eval "su $lname -c \"$cmd\"" + fi + + # Note failure of the command. Also, send a message + # that the command is done. We will know we're done + # reading from the daemon when we see this message. + fail_flag=$? + $1/send_msg over + print + + # Reset variables for reading this command. + event_count=0 + unset contents event fs_handle handle length offset + unset media_designator mode mountpoint_handle + unset mountpoint_path msg_str name new_name new_parent + unset parent_handle ret_code root_handle sequence token + unset tries_left unmount_mode + + # Read events, report them, and store their data. + while true + do + read -p event[event_count] + case "${event[event_count]}" in + mount) + print "Report: found mount event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk fs_handle[event_count] + read -p junk mountpoint_handle[event_count] + read -p junk mountpoint_path[event_count] + read -p junk media_designator[event_count] + read -p junk root_handle[event_count] + read -p junk mode[event_count] + read -p junk;; + preunmount) + print "Report: found preunmount event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk fs_handle[event_count] + read -p junk root_handle[event_count] + read -p junk unmount_mode[event_count] + read -p junk;; + unmount) + print "Report: found unmount event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk fs_handle[event_count] + read -p junk unmount_mode[event_count] + read -p junk ret_code[event_count] + read -p junk;; + nospace) + print "Report: found nospace event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk fs_handle[event_count] + read -p junk;; + create|remove) + print "Report: found ${event[event_count]} event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk parent_handle[event_count] + read -p junk name[event_count] + read -p junk mode[event_count] + read -p junk;; + postcreate) + print "Report: found postcreate event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk parent_handle[event_count] + read -p junk handle[event_count] + read -p junk name[event_count] + read -p junk mode[event_count] + read -p junk ret_code[event_count] + read -p junk;; + postremove) + print "Report: found postremove event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk parent_handle[event_count] + read -p junk name[event_count] + read -p junk mode[event_count] + read -p junk ret_code[event_count] + read -p junk;; + rename) + print "Report: found rename event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk parent_handle[event_count] + read -p junk new_parent[event_count] + read -p junk name[event_count] + read -p junk new_name[event_count] + read -p junk;; + postrename) + print "Report: found postrename event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk parent_handle[event_count] + read -p junk new_parent[event_count] + read -p junk name[event_count] + read -p junk new_name[event_count] + read -p junk ret_code[event_count] + read -p junk;; + symlink) + print "Report: found symlink event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk parent_handle[event_count] + read -p junk name[event_count] + read -p junk contents[event_count] + read -p junk;; + postsymlink) + print "Report: found postsymlink event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk parent_handle[event_count] + read -p junk handle[event_count] + read -p junk name[event_count] + read -p junk contents[event_count] + read -p junk ret_code[event_count] + read -p junk;; + link) + print "Report: found link event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk parent_handle[event_count] + read -p junk handle[event_count] + read -p junk name[event_count] + read -p junk;; + postlink) + print "Report: found postlink event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk parent_handle[event_count] + read -p junk handle[event_count] + read -p junk name[event_count] + read -p junk ret_code[event_count] + read -p junk;; + read|write|truncate) + print "Report: found ${event[event_count]} event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk handle[event_count] + read -p junk offset[event_count] + read -p junk length[event_count] + read -p junk;; + attribute) + print "Report: found attribute event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk handle[event_count] + read -p junk;; + destroy) + print "Report: found destroy event." + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk handle[event_count] + read -p junk name[event_count] + read -p junk contents[event_count] + read -p junk;; + user) + read -p junk token[event_count] + read -p junk sequence[event_count] + read -p junk msg_str[event_count] + case "${msg_str[event_count]}" in + "over") read -p junk + event[event_count]=end_of_tests + print "Report: found \"end of test\" user event. " + break;; + *) print "Report: found user event. " + read -p junk;; + esac;; + pending) + read -p junk tries_left[event_count] + print -n "Report: process pending. " + print "Tries left: ${tries_left[event_count]}" + read -p junk;; + *) + print -n "Report: found ${event[event_count]} event. " + print "(unknown to this version)" + while read -p msg_str[event_count] + do case "${msg_str[event_count]}" in + "end_of_message") break;; + *);; + esac + done;; + esac + ((event_count=event_count+1)) + done + ((old_error_count=error_count)); + + IFS=" " + + while read -u3 val_one val_two val_tre + do case $val_one in + ---*) if [[ $fail_flag != -1 ]] + then if [[ $fail_flag != 0 ]] + then print -n "ERROR: command failed; it was " + print "expected to succeed." + ((error_count=error_count+1)) + fi + fi + if (( error_count>old_error_count || pause_flag==1 )) + then print "\nEnter q to quit, or press enter to continue..." + read go + case "$go" in + q|Q) break;; + *);; + esac + fi + IFS=":" + continue 2;; + failure) + if [[ $fail_flag = 0 ]] + then print "ERROR: command succeeded; it was expected to fail." + ((error_count=error_count+1)) + else print "Note: command is expected to fail." + fi + fail_flag=-1;; + *) case $val_two in + matches) + if [[ $(eval "print $"{$val_one}) = $(eval "print $"{$val_tre}) ]] + then print "Report: $val_one and $val_tre match; both are " + if [[ $(eval "print $"{$val_one}) = "" ]] + then print "unset" + else print "$(eval "print $"{$val_one})" + fi + else print -n "ERROR: $val_one was " + if [[ $(eval "print $"{$val_one}) = "" ]] + then print -n "unset " + else print -n "equal to $(eval "print $"{$val_one})" + fi + print -n ", while $val_tre was " + if [[ $(eval "print $"{$val_tre}) = "" ]] + then print "unset." + else print "equal to $(eval "print $"{$val_tre})." + fi + ((error_count=error_count+1)) + fi;; + store_in) + eval ${val_tre}=$(eval "print $"{$val_one}) + print -n "Report: value of ${val_one} copied into " + print "${val_tre}.";; + *) + if [[ $(eval "print $"{$val_one}) = $val_two ]] + then : + else if [[ "$val_one" = event_count ]] + then print -n "ERROR: expected $val_two event(s), " + print "but found $event_count." + else print -n "ERROR: $val_one was " + if [[ $(eval "print $"{$val_one}) = "" ]] + then print -n "unset " + else print -n "equal to $(eval "print $"{$val_one}) " + fi + print "rather than $val_two as expected." + fi + ((error_count=error_count+1)) + fi;; + esac;; + esac + done + if [[ $fail_flag != -1 ]] + then if [[ $fail_flag != 0 ]] + then print -n "ERROR: command failed; it was " + print "expected to succeed." + ((error_count=error_count+1)) + fi + fi + if (( error_count>old_error_count || pause_flag==1 )) + then print "\nTests complete. Press enter to quit..." + read go + fi + break +done + +# Close the datafile +exec 3<&- + +# End the daemon +kill $coproc +wait $coproc + +clear +if ((error_count==1)) +then print "Test result: 1 error found." +else print "Test result: $error_count errors found." +fi diff --git a/dmapi/src/suite2/bindir/stf b/dmapi/src/suite2/bindir/stf new file mode 100755 index 000000000..a0fe3c8d7 --- /dev/null +++ b/dmapi/src/suite2/bindir/stf @@ -0,0 +1,41 @@ +#!/bin/ksh +# +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +sr_dir=$1 +shift 1 + +for i in $* + do + attr -Rq -s SGI_DMI_test -V123456789abcdefghijklmnopqrstuvwxyz $i + $sr_dir/set_region $i DM_REGION_READ DM_REGION_WRITE DM_REGION_TRUNCATE > /dev/null + done diff --git a/dmapi/src/suite2/bindir/test_allocinfo_1 b/dmapi/src/suite2/bindir/test_allocinfo_1 new file mode 100755 index 000000000..b37b3169a --- /dev/null +++ b/dmapi/src/suite2/bindir/test_allocinfo_1 @@ -0,0 +1,100 @@ +#!/bin/ksh + +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + + +# Dump the same holey file using both xfs_bmap and +# dump_allocinfo (a C wrapper for get_allocinfo). +# Run awk on the xfs_bmap output, since xfs_bmap +# gives specific block allocation info that get_allocinfo +# does not. Then diff the two outputs. + +if [[ $# != 2 ]] +then print "USAGE: ${0##*/} bindir testdir" + exit 1 +fi + +# Check bindir for needed programs. +if [[ ! ( -r "$1/wf" ) ]] +then print "Aborting: necessary program wf is not in $1/." + if [[ ! ( -r "$1/dump_allocinfo" ) ]] + then print " necessary program dump_allocinfo is also missing." + fi + exit 1 +fi +if [[ ! ( -r "$1/dump_allocinfo" ) ]] +then print "Aborting: necessary program dump_allocinfo is not in $1/." + exit 1 +fi + +print "Comparison test (get_allocinfo vs. xfs_bmap) beginning..." + +typeset -i offset +typeset -i length +typeset -i count + +RANDOM=$SECONDS +offset=0 +length=$RANDOM +count=100 +filename=DMAPI_test_allocinfo + +# Create a random holey file +while (( count > 0 )) +do + $1/wf -l $length -L $offset -b 512 $2/$filename > /dev/null + (( offset = RANDOM * 512 + offset + length )) + (( length = RANDOM )) + (( count = count - 1 )) +done + +# Get output from xfs_bmap +xfs_bmap $2/DMAPI_test_allocinfo > $2/$filename.xfs + +# Get output from dump_allocinfo (DMAPI) +$1/dump_allocinfo $2/DMAPI_test_allocinfo > $2/$filename.da + +# Alter xfs_bmap ouput to match get_allocinfo +awk '{ if (NR > 1) + if ($3 == "hole") + print $1, $2, $3 + else + print $1, $2, "resv" +}' $2/DMAPI_test_allocinfo.xfs > $2/$filename.ok + +# Compare the ouput +diff -w $2/$filename.ok $2/$filename.da + +# Remove the test file +rm $2/$filename* + +print "Test complete." diff --git a/dmapi/src/suite2/bindir/test_allocinfo_2 b/dmapi/src/suite2/bindir/test_allocinfo_2 new file mode 100755 index 000000000..e3a3e36d1 --- /dev/null +++ b/dmapi/src/suite2/bindir/test_allocinfo_2 @@ -0,0 +1,100 @@ +#!/bin/ksh + +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +# Dump the same holey file a random number of times, each time +# using one less extent structure than the previous time. +# The grep and diff code checks to make sure that you get the +# same answer each time, no matter how many extents you use. + +typeset -i offset +typeset -i length +typeset -i max + +# Verify correct usage +if [[ $# != 2 ]] +then print "usage: ${0##*/} bindir testdir" + exit 1 +fi + +# Check bindir for needed programs. +if [[ ! ( -r "$1/wf" ) ]] +then print "Aborting: necessary program wf is not in $1/." + if [[ ! ( -r "$1/dump_allocinfo" ) ]] + then print " necessary program dump_allocinfo is also missing." + fi + exit 1 +fi +if [[ ! ( -r "$1/dump_allocinfo" ) ]] +then print "Aborting: necessary program dump_allocinfo is not in $1/." + exit 1 +fi + +print "Multiple-buffer-sizes test of get_allocinfo beginning..." + +RANDOM=$SECONDS +offset=0 +length=$RANDOM +filename=DMAPI_alloc_test_2 +((max = $RANDOM/256)) +count=$max + +# Holey file creation: put about $max holes into the file. +while (( count > 0 )) +do + $1/wf -l $length -L $offset -b 512 $2/$filename > /dev/null + (( offset = RANDOM * 512 + offset + length )) + (( length = RANDOM )) + (( count = count - 1 )) +done +count=$max + +# Now count down from $max to 1 and try dump_allocinfo with a buffer that +# can hold that many dm_extent_t structures. +while [[ $count > 0 ]] +do + $1/dump_allocinfo -n $count $2/$filename | grep '\[' > $2/x.$count + if (( count < max )) + then diff $2/x.$count $2/x.$max > /dev/null + if [[ $? != 0 ]] + then print "ERROR in trial #$count:" + diff $2/x.$count $2/x.$max + fi + rm $2/x.$count + fi + (( count = count - 1 )) +done + +rm $2/x.$max +rm $2/$filename + +print "Test complete." diff --git a/dmapi/src/suite2/create_cpio b/dmapi/src/suite2/create_cpio new file mode 100644 index 000000000..92f626bac --- /dev/null +++ b/dmapi/src/suite2/create_cpio @@ -0,0 +1,37 @@ +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +rm /home/hickory43/jayw/test/dist/DMAPI_test.cpio +cd /home/hickory43/jayw/test +find * \( ! -name '*.o' ! -name '*~' ! -name './dist/*' \) | cpio -oc > /home/hickory43/jayw/test/dist/DMAPI_test.cpio +cp /home/hickory43/jayw/test/README /home/hickory43/jayw/test/dist/README +cd /home/hickory43/jayw/test/dist + diff --git a/dmapi/src/suite2/data/fail.dat b/dmapi/src/suite2/data/fail.dat new file mode 100644 index 000000000..c8dfb0bd0 --- /dev/null +++ b/dmapi/src/suite2/data/fail.dat @@ -0,0 +1,118 @@ +// +// Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of version 2 of the GNU General Public License as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it would be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// Further, this software is distributed without any warranty that it is +// free of the rightful claim of any third person regarding infringement +// or the like. Any license provided herein, whether implied or +// otherwise, applies only to this software file. Patent licenses, if +// any, provided herein do not apply to combinations of this program with +// other software, or any other product whatsoever. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write the Free Software Foundation, Inc., 59 +// Temple Place - Suite 330, Boston MA 02111-1307, USA. +// +// Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +// Mountain View, CA 94043, or: +// +// http://www.sgi.com +// +// For further information regarding this notice, see: +// +// http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +// This test will use the following files: +// +ctf stf ls_to_copy ctest.c +fcntl open_test truncate rd wf +set_region set_return_on_destroy +-------------------------------------------- +// These setup commands are run before the daemon starts. +// They reset the file structure of the test directory +// to a known state, and they ensure that the NFS +// +rm $real_dir/??? +$1/ctf $1 $real_dir +$1/stf $1 $real_dir/l?? +rm $real_dir/ctest.c +cp $1/ctest.c $real_dir +chown $lname $real_dir/* +$1/set_return_on_destroy $real_dir test +rmdir $real_dir/fail_tempdir/fail_subdir +rm $real_dir/fail_tempdir/* +rmdir $real_dir/fail_tempdir +mkdir $real_dir/fail_tempdir +mkdir $real_dir/fail_tempdir/fail_subdir +echo "Temporary file" > $real_dir/fail_tempdir/temp_file +chown root $real_dir/fail_tempdir +-------------------------------------------- +@@ Failure checks (1 of 8): symlink +@@ +ln -s $2/fail_tempdir/temp_file $2/fail_tempdir/failed_symlink +event_count 2 +event[0] symlink +event[1] postsymlink +ret_code[1] 13 +failure +-------------------------------------------- +@@ Failure checks (2 of 8): link +@@ +ln $2/fail_tempdir/temp_file $2/fail_tempdir/failed_link +event_count 2 +event[0] link +event[1] postlink +ret_code[1] 13 +failure +-------------------------------------------- +@@ Failure checks (3 of 8): mkdir +@@ +mkdir $2/fail_tempdir/failed_subdir +event_count 2 +event[0] create +event[1] postcreate +ret_code[1] 13 +failure +-------------------------------------------- +@@ Failure checks (4 of 8): rmdir +@@ +rmdir $2/fail_tempdir/fail_subdir +event_count 2 +event[0] remove +event[1] postremove +ret_code[1] 13 +failure +-------------------------------------------- +@@ Failure checks (5 of 8): open +@@ +$1/open_test $2/fail_tempdir/temp_file o_rdwr +event_count 0 +failure +-------------------------------------------- +@@ Failure checks (6 of 8): open/create +@@ +$1/open_test $2/fail_tempdir/temp_file o_rdwr o_creat +event_count 0 +failure +-------------------------------------------- +@@ Failure checks (7 of 8): open/truncate +@@ +$1/open_test $2/fail_tempdir/temp_file o_rdwr o_trunc +event_count 0 +failure +-------------------------------------------- +@@ Failure checks (8 of 8): remove +@@ +rm -f $2/fail_tempdir/temp_file +event_count 2 +event[0] remove +event[1] postremove +ret_code[1] 13 +failure diff --git a/dmapi/src/suite2/data/main.dat b/dmapi/src/suite2/data/main.dat new file mode 100644 index 000000000..ae2f4b5a7 --- /dev/null +++ b/dmapi/src/suite2/data/main.dat @@ -0,0 +1,159 @@ +// +// Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of version 2 of the GNU General Public License as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it would be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// Further, this software is distributed without any warranty that it is +// free of the rightful claim of any third person regarding infringement +// or the like. Any license provided herein, whether implied or +// otherwise, applies only to this software file. Patent licenses, if +// any, provided herein do not apply to combinations of this program with +// other software, or any other product whatsoever. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write the Free Software Foundation, Inc., 59 +// Temple Place - Suite 330, Boston MA 02111-1307, USA. +// +// Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +// Mountain View, CA 94043, or: +// +// http://www.sgi.com +// +// For further information regarding this notice, see: +// +// http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +// This test will use the following files: +// +ctf stf ls_to_copy ctest.c +fcntl open_test truncate rd wf +read_invis write_invis +set_region set_return_on_destroy +-------------------------------------------- +// These setup commands are run before the daemon starts. +// They reset the file structure of the test directory +// to a known state. +// +rm $real_dir/??? +rm $real_dir/ctest.c +$1/ctf $1 $real_dir +$1/stf $1 $real_dir/l?? +cp $1/ctest.c $real_dir +chown $lname $real_dir/l?? +chown $lname $real_dir/ctest.c +$1/set_return_on_destroy $real_dir test +-------------------------------------------- +@@ Aborted events testing (1 of 7): +@@ Read ls0 successfully. +@@ +$1/open_test $2/ls0 o_rdwr +event_count 1 +event[0] read +-------------------------------------------- +@@ Aborted events testing (2 of 7): +@@ Set the daemon to halt events with DM_RESP_ABORT +@@ and errno EEXIST. +@@ +run_as_root +$1/send_msg unfriendly_17 +event_count 1 +event[0] user +msg_str[0] unfriendly_17 +-------------------------------------------- +@@ Aborted events testing (3 of 7): +@@ Try to read ls0. this should fail with EEXIST. +@@ +$1/open_test $2/ls0 o_rdwr +event_count 1 +event[0] read +failure +-------------------------------------------- +@@ Aborted events testing (4 of 7): +@@ Try to read ls1. This should fail with EEXIST. +@@ +$1/open_test $2/ls1 o_rdwr o_trunc +event_count 1 +event[0] truncate +failure +-------------------------------------------- +@@ Aborted events testing (5 of 7): +@@ Reset the daemon to respond with DM_RESP_CONTINUE. +@@ +run_as_root +$1/send_msg friendly +event_count 1 +event[0] user +msg_str[0] friendly +-------------------------------------------- +@@ Aborted events testing (6 of 7): +@@ Again, try to read ls0. This should succeed. +@@ +$1/open_test $2/ls0 o_rdwr +event_count 1 +event[0] read +-------------------------------------------- +@@ Aborted events testing (7 of 7): +@@ Again, try to read ls1. This time, +@@ it should succeed. +@@ +$1/open_test $2/ls1 o_rdwr o_trunc +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ dm_send_msg test +@@ +run_as_root +$1/send_msg dmapi-test-foo-abc123 +event_count 1 +event[0] user +msg_str[0] dmapi-test-foo-abc123 +-------------------------------------------- +@@ Test of invisible i/o (1 of 2): write +@@ +run_as_root +$1/write_invis -o 64 -l 16 $2/ls0 +event_count 0 +-------------------------------------------- +@@ Test of invisible i/o (2 of 2): read +@@ +run_as_root +$1/read_invis -o 64 -l 16 $2/ls0 +event_count 0 +-------------------------------------------- +@@ Test of direct i/o (1 of 2): write +@@ +$1/wf -l 327680 -b 32768 -d $2/ls9 +event_count 10 +event[0] write +event[1] write +event[2] write +event[3] write +event[4] write +event[5] write +event[6] write +event[7] write +event[8] write +event[9] write +-------------------------------------------- +@@ Test of direct i/o (2 of 2): read +@@ +$1/rd -b 32768 -d $2/ls9 +event_count 11 +event[0] read +event[1] read +event[2] read +event[3] read +event[4] read +event[5] read +event[6] read +event[7] read +event[8] read +event[9] read +event[10] read diff --git a/dmapi/src/suite2/data/nfs.dat b/dmapi/src/suite2/data/nfs.dat new file mode 100644 index 000000000..601f81156 --- /dev/null +++ b/dmapi/src/suite2/data/nfs.dat @@ -0,0 +1,174 @@ +// +// Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of version 2 of the GNU General Public License as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it would be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// Further, this software is distributed without any warranty that it is +// free of the rightful claim of any third person regarding infringement +// or the like. Any license provided herein, whether implied or +// otherwise, applies only to this software file. Patent licenses, if +// any, provided herein do not apply to combinations of this program with +// other software, or any other product whatsoever. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write the Free Software Foundation, Inc., 59 +// Temple Place - Suite 330, Boston MA 02111-1307, USA. +// +// Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +// Mountain View, CA 94043, or: +// +// http://www.sgi.com +// +// For further information regarding this notice, see: +// +// http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +// This test will use the following files: +// +ctf stf ls_to_copy ctest.c +fcntl open_test truncate rd wf +set_region set_return_on_destroy +-------------------------------------------- +// These setup commands are run before the daemon starts. +// They reset the file structure of the test directory +// to a known state. +// +rm $real_dir/??? +$1/ctf $1 $real_dir +$1/stf $1 $real_dir/l?? +chown $lname $real_dir/l?? +$1/set_return_on_destroy $real_dir test +-------------------------------------------- +@@ Aborted events testing (1 of 7): +@@ Bring ls0 across NFS, causing it to be cached. +@@ +$1/open_test $2/ls0 o_rdwr +event_count 1 +event[0] read +-------------------------------------------- +@@ Aborted events testing (2 of 7): +@@ Set the daemon to halt events with DM_RESP_ABORT +@@ and errno EEXIST. +@@ +run_as_root +$1/send_msg unfriendly_17 +event_count 1 +event[0] user +msg_str[0] unfriendly_17 +-------------------------------------------- +@@ Aborted events testing (3 of 7): +@@ Try to read ls0. Since it is cached, this should succeed. +@@ and should not generate any events. +@@ +$1/open_test $2/ls0 o_rdwr +event_count 0 +-------------------------------------------- +@@ Aborted events testing (4 of 7): +@@ Try to read ls1. This should fail with EEXIST. +@@ +$1/open_test $2/ls1 o_rdwr o_trunc +event_count 1 +event[0] truncate +failure +-------------------------------------------- +@@ Aborted events testing (5 of 7): +@@ Reset the daemon to respond with DM_RESP_CONTINUE. +@@ +run_as_root +$1/send_msg friendly +event_count 1 +event[0] user +msg_str[0] friendly +-------------------------------------------- +@@ Aborted events testing (6 of 7): +@@ Again, try to read ls0. It will be in the cache, +@@ so no events should occur. +@@ +$1/open_test $2/ls0 o_rdwr +event_count 0 +-------------------------------------------- +@@ Aborted events testing (7 of 7): +@@ Again, try to read ls1. This time, +@@ it should succeed. +@@ +$1/open_test $2/ls1 o_rdwr o_trunc +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ dm_send_msg test +@@ +run_as_root +$1/send_msg dmapi-test-foo-abc123 +event_count 1 +event[0] user +msg_str[0] dmapi-test-foo-abc123 +-------------------------------------------- +@@ NFS test: DM_RESP_ABORT (1 of 3) +@@ +// For the next two events, respond with +// DM_RESP_ABORT and errno 4 The first +// open test of ls1 should fail; the +// second should succeed. +// +run_as_root +$1/send_msg countdown_2_4 +event_count 1 +event[0] user +msg_str[0] countdown_2_4 +-------------------------------------------- +@@ NFS test: DM_RESP_ABORT (2 of 3) +@@ +$1/open_test $2/ls2 o_rdwr +event_count 1 +event[0] read +failure +-------------------------------------------- +@@ NFS test: DM_RESP_ABORT (3 of 3) +@@ +$1/open_test $2/ls2 o_rdwr +event_count 1 +event[0] read +-------------------------------------------- +@@ NFS test: EAGAIN (1 of 4) +@@ +// For the next two events, respond with +// DM_RESP_ABORT and errno 11 -- EAGAIN. +// NFS should retry sending the event as +// long as EAGAIN is returned. +// +run_as_root +$1/send_msg countdown_2_11 +event_count 1 +event[0] user +msg_str[0] countdown_2_11 +-------------------------------------------- +@@ NFS test: EAGAIN (2 of 4) +@@ +$1/open_test $2/ls3 o_rdwr +event_count 2 +event[0] read +event[1] read +-------------------------------------------- +@@ NFS test: EAGAIN (3 of 4) +@@ +run_as_root +$1/send_msg countdown_4_11 +event_count 1 +event[0] user +msg_str[0] countdown_4_11 +-------------------------------------------- +@@ NFS test: EAGAIN (4 of 4) +@@ +$1/open_test $2/ls4 o_rdwr +event_count 4 +event[0] read +event[1] read +event[2] read +event[3] read diff --git a/dmapi/src/suite2/data/pending.dat b/dmapi/src/suite2/data/pending.dat new file mode 100644 index 000000000..794b58622 --- /dev/null +++ b/dmapi/src/suite2/data/pending.dat @@ -0,0 +1,90 @@ +// +// Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of version 2 of the GNU General Public License as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it would be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// Further, this software is distributed without any warranty that it is +// free of the rightful claim of any third person regarding infringement +// or the like. Any license provided herein, whether implied or +// otherwise, applies only to this software file. Patent licenses, if +// any, provided herein do not apply to combinations of this program with +// other software, or any other product whatsoever. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write the Free Software Foundation, Inc., 59 +// Temple Place - Suite 330, Boston MA 02111-1307, USA. +// +// Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +// Mountain View, CA 94043, or: +// +// http://www.sgi.com +// +// For further information regarding this notice, see: +// +// http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +// This test will use the following files: +// +ctf stf ls_to_copy set_region +-------------------------------------------- +// These setup commands are run before the daemon starts. +// They reset the file structure of the test directory +// to a known state. +// +rm $real_dir/??? +$1/ctf $1 $real_dir +$1/stf $1 $real_dir/l?? +chown $lname $real_dir/l?? +-------------------------------------------- +@@ Pending test (1 of 5): +@@ +// Run "pending" for the next 3 events, +// so that a non-blocking open_test +// will see EAGAIN three times before +// it can finish. +// +run_as_root +$1/send_msg pending_3 +event_count 1 +event[0] user +msg_str[0] pending_3 +-------------------------------------------- +@@ Pending test (2 of 5): +@@ (should fail) +@@ +$1/open_test $2/ls1 o_rdwr o_nonblock +event_count 1 +event[0] pending +tries_left[0] 2 +failure +-------------------------------------------- +@@ Pending test (3 of 5): +@@ (should fail) +@@ +$1/open_test $2/ls1 o_rdwr o_ndelay +event_count 1 +event[0] pending +tries_left[0] 1 +failure +-------------------------------------------- +@@ Pending test (4 of 5): +@@ (should fail) +@@ +$1/open_test $2/ls1 o_rdwr o_nonblock o_ndelay +event_count 1 +event[0] pending +tries_left[0] 0 +failure +-------------------------------------------- +@@ Pending test (5 of 5): +@@ (should succeed) +@@ +$1/open_test $2/ls1 o_rdwr o_nonblock +event_count 1 +event[0] read diff --git a/dmapi/src/suite2/data/pending_nfs.dat b/dmapi/src/suite2/data/pending_nfs.dat new file mode 100644 index 000000000..3b677af10 --- /dev/null +++ b/dmapi/src/suite2/data/pending_nfs.dat @@ -0,0 +1,72 @@ +// +// Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of version 2 of the GNU General Public License as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it would be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// Further, this software is distributed without any warranty that it is +// free of the rightful claim of any third person regarding infringement +// or the like. Any license provided herein, whether implied or +// otherwise, applies only to this software file. Patent licenses, if +// any, provided herein do not apply to combinations of this program with +// other software, or any other product whatsoever. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write the Free Software Foundation, Inc., 59 +// Temple Place - Suite 330, Boston MA 02111-1307, USA. +// +// Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +// Mountain View, CA 94043, or: +// +// http://www.sgi.com +// +// For further information regarding this notice, see: +// +// http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +// This test will use the following files: +// +ctf stf ls_to_copy set_region +-------------------------------------------- +// These setup commands are run before the daemon starts. +// They reset the file structure of the test directory +// to a known state. +// +rm $real_dir/??? +$1/ctf $1 $real_dir +$1/stf $1 $real_dir/l?? +chown $lname $real_dir/l?? +-------------------------------------------- +@@ NFS test: pending (1 of 2) +@@ +// Run "pending" for the next 3 events, +// so that ls0 will trigger 3 pending +// pseudo-events before succeeding +// +run_as_root +$1/send_msg pending_3 +event_count 1 +event[0] user +msg_str[0] pending_3 +-------------------------------------------- +@@ NFS test: pending (2 of 2) +@@ +@@ (this will take a while...) +@@ +$2/ls0 -l $real_dir +event_count 7 +event[0] pending +event[1] pending +event[2] pending +event[3] read +event[4] read +event[5] read +event[6] read +tries_left[0] 2 +tries_left[1] 1 +tries_left[2] 0 diff --git a/dmapi/src/suite2/data/realtime.dat b/dmapi/src/suite2/data/realtime.dat new file mode 100644 index 000000000..a74e16ce2 --- /dev/null +++ b/dmapi/src/suite2/data/realtime.dat @@ -0,0 +1,139 @@ +// +// Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of version 2 of the GNU General Public License as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it would be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// Further, this software is distributed without any warranty that it is +// free of the rightful claim of any third person regarding infringement +// or the like. Any license provided herein, whether implied or +// otherwise, applies only to this software file. Patent licenses, if +// any, provided herein do not apply to combinations of this program with +// other software, or any other product whatsoever. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write the Free Software Foundation, Inc., 59 +// Temple Place - Suite 330, Boston MA 02111-1307, USA. +// +// Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +// Mountain View, CA 94043, or: +// +// http://www.sgi.com +// +// For further information regarding this notice, see: +// +// http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +// This test will use the following files: +// +stf crttf new_wf +fcntl open_test truncate rd wf +read_invis write_invis +set_region set_return_on_destroy +-------------------------------------------- +// These setup commands are run before the daemon starts. +// They reset the file structure of the test directory +// to a known state. +// +rm $real_dir/realtime.? +$1/crttf $1 $real_dir +chown $lname $real_dir/* +$1/stf $1 $real_dir/realtime.? +$1/set_return_on_destroy $real_dir test +-------------------------------------------- +@@ Test of invisible i/o (1 of 2): write +@@ +run_as_root +$1/write_invis -o 64 -l 16 $2/realtime.0 +event_count 0 +-------------------------------------------- +@@ Test of invisible i/o (2 of 2): read +@@ +run_as_root +$1/read_invis -o 64 -l 16 $2/realtime.0 +event_count 0 +-------------------------------------------- +@@ Test of direct i/o (1 of 2): write +@@ +$1/wf -l 327680 -b 32768 -d $2/realtime.1 +event_count 10 +event[0] write +event[1] write +event[2] write +event[3] write +event[4] write +event[5] write +event[6] write +event[7] write +event[8] write +event[9] write +-------------------------------------------- +@@ Test of direct i/o (2 of 2): read +@@ +$1/rd -b 32768 -d $2/realtime.1 +event_count 11 +event[0] read +event[1] read +event[2] read +event[3] read +event[4] read +event[5] read +event[6] read +event[7] read +event[8] read +event[9] read +event[10] read +-------------------------------------------- +@@ Standard i/o tests (1 of 7): open +@@ +$1/open_test $2/realtime.2 o_rdwr +event_count 1 +event[0] read +-------------------------------------------- +@@ Standard i/o tests (2 of 7): open/trunc +@@ +$1/open_test $2/realtime.3 o_rdwr o_trunc +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (3 of 7): open/trunc/create +@@ +$1/open_test $2/realtime.4 o_rdwr o_trunc o_creat +event_count 1 +event[0] truncate +-------------------------------------------- +@@ Standard i/o tests (4 of 7): open/create +@@ +$1/open_test $2/realtime.5 o_rdwr o_creat +event_count 1 +event[0] read +-------------------------------------------- +@@ Standard i/o tests (5 of 7): append #1 +@@ +echo j >> $2/realtime.6 +event_count 1 +event[0] write +file_handle[0] store_in ls4temp +-------------------------------------------- +@@ Standard i/o tests (6 of 7): append #2 +@@ +echo w >> $2/realtime.6 +event_count 1 +event[0] write +file_handle[0] matches ls4temp +-------------------------------------------- +@@ Standard i/o tests (7 of 7): remove +@@ +/bin/rm $2/realtime.6 +event_count 3 +event[0] remove +event[1] destroy +event[2] postremove +name[1] test +contents[1] 123456789abcdefghijklmnopqrstuvwxyz diff --git a/dmapi/src/suite2/data/smallq.dat b/dmapi/src/suite2/data/smallq.dat new file mode 100644 index 000000000..dfc7fcb08 --- /dev/null +++ b/dmapi/src/suite2/data/smallq.dat @@ -0,0 +1,106 @@ +// +// Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of version 2 of the GNU General Public License as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it would be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// Further, this software is distributed without any warranty that it is +// free of the rightful claim of any third person regarding infringement +// or the like. Any license provided herein, whether implied or +// otherwise, applies only to this software file. Patent licenses, if +// any, provided herein do not apply to combinations of this program with +// other software, or any other product whatsoever. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write the Free Software Foundation, Inc., 59 +// Temple Place - Suite 330, Boston MA 02111-1307, USA. +// +// Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +// Mountain View, CA 94043, or: +// +// http://www.sgi.com +// +// For further information regarding this notice, see: +// +// http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +// This test will use the following files: +// +ctf stf ls_to_copy ctest.c +fcntl open_test truncate rd wf mmap_cp +read_invis write_invis +set_region set_return_on_destroy +-------------------------------------------- +// These setup commands are run before the daemon starts. +// They reset the file structure of the test directory +// to a known state. +// +rm $real_dir/??? +$1/ctf $1 $real_dir +$1/stf $1 $real_dir/l?? +rm $real_dir/ctest.c +cp $1/ctest.c $real_dir +chown $lname $real_dir/l?? +chown $lname $real_dir/ctest.c +$1/set_return_on_destroy $real_dir test +print +print "Please resize your DMAPI event queue to hold about 2 to 10 events." +-------------------------------------------- +@@ Slow i/o test: Do 10 open_tests +@@ +run_without_test +$1/open_test $2/ls0 o_rdwr & +$1/open_test $2/ls0 o_rdwr & +$1/open_test $2/ls0 o_rdwr & +$1/open_test $2/ls0 o_rdwr & +$1/open_test $2/ls0 o_rdwr & +$1/open_test $2/ls0 o_rdwr & +$1/open_test $2/ls0 o_rdwr & +$1/open_test $2/ls0 o_rdwr & +$1/open_test $2/ls0 o_rdwr & +$1/open_test $2/ls0 o_rdwr & +-------------------------------------------- +@@ Slow i/o test: Append ten bytes to ls1 +@@ +run_without_test +echo J >> $2/ls1 & +echo a >> $2/ls1 & +echo y >> $2/ls1 & +echo w >> $2/ls1 & +echo a >> $2/ls1 & +echo s >> $2/ls1 & +echo h >> $2/ls1 & +echo e >> $2/ls1 & +echo r >> $2/ls1 & +echo e >> $2/ls1 & +-------------------------------------------- +@@ Slow i/o test: Do one more, then stand back and wait! +@@ +$1/open_test $2/ls0 o_rdwr +event_count 21 +event[0] read +event[1] read +event[2] read +event[3] read +event[4] read +event[5] read +event[6] read +event[7] read +event[8] read +event[9] read +event[10] write +event[11] write +event[12] write +event[13] write +event[14] write +event[15] write +event[16] write +event[17] write +event[18] write +event[19] write +event[20] read diff --git a/dmapi/src/suite2/data/standard.dat b/dmapi/src/suite2/data/standard.dat new file mode 100644 index 000000000..684dff95e --- /dev/null +++ b/dmapi/src/suite2/data/standard.dat @@ -0,0 +1,323 @@ +// +// Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of version 2 of the GNU General Public License as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it would be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// Further, this software is distributed without any warranty that it is +// free of the rightful claim of any third person regarding infringement +// or the like. Any license provided herein, whether implied or +// otherwise, applies only to this software file. Patent licenses, if +// any, provided herein do not apply to combinations of this program with +// other software, or any other product whatsoever. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write the Free Software Foundation, Inc., 59 +// Temple Place - Suite 330, Boston MA 02111-1307, USA. +// +// Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +// Mountain View, CA 94043, or: +// +// http://www.sgi.com +// +// For further information regarding this notice, see: +// +// http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +// This test will use the following files: +// +ctf stf ls_to_copy ctest.c +fcntl open_test truncate rd wf mmap_cp +read_invis write_invis +set_region set_return_on_destroy +-------------------------------------------- +// These setup commands are run before the daemon starts. +// They reset the file structure of the test directory +// to a known state. +// +rm $real_dir/??? +rm $real_dir/mmap_cp_testfile +$1/ctf $1 $real_dir +$1/stf $1 $real_dir/l?? +rm $real_dir/ctest.c +cp $1/ctest.c $real_dir +chown $lname $real_dir/l?? +chown $lname $real_dir/ctest.c +$1/set_return_on_destroy $real_dir test +-------------------------------------------- +@@ Memory-mapped copying test: (1 of 3) +@@ +$1/mmap_cp $2/ll1 $2/mmap_cp_testfile +event_count 3 +event[0] create +event[1] postcreate +event[2] read +-------------------------------------------- +@@ Memory-mapped copying test: (2 of 3) +@@ +$1/mmap_cp $2/ll1 $2/mmap_cp_testfile +event_count 1 +event[0] read +-------------------------------------------- +@@ Memory-mapped copying test: (3 of 3) +@@ +$1/mmap_cp $2/ll1 $2/ll2 +event_count 2 +event[0] read +event[1] write +-------------------------------------------- +@@ Preunmount/unmount test +@@ (note: if you abort before the next test, the +@@ filesystem will remain unmounted) +@@ +run_as_root +umount $3 +event_count 2 +event[0] preunmount +event[1] unmount +fs_handle[0] matches fs_handle[1] +fs_handle[0] store_in fsh +root_handle[0] store_in rh +unmount_mode[0] NOFORCE +unmount_mode[1] NOFORCE +-------------------------------------------- +@@ Mount test +@@ (Note: assorted settings will be restored in next tests) +@@ +run_as_root +mount $3 +event_count 1 +event[0] mount +fs_handle[0] matches fsh +mountpoint_handle[0] +mountpoint_path[0] /dmitest +mode[0] 0 +root_handle matches rh +-------------------------------------------- +@@ (after remount: restoring event dispositions on fs) +@@ +run_as_root +$1/send_msg reset_fs +event_count 1 +event[0] user +msg_str[0] reset_fs +-------------------------------------------- +@@ (after remount: restoring managed regions on files +@@ and setting destroy events to return "test" attribute) +@@ +run_without_test +$1/stf $1 $real_dir/l?? +$1/set_return_on_destroy $real_dir test +------------------------------------------- +@@ Standard i/o tests (1 of 26): open +@@ +$1/open_test $2/ls0 o_rdwr +event_count 1 +event[0] read +-------------------------------------------- +@@ Standard i/o tests (2 of 26): open/trunc +@@ +$1/open_test $2/ls1 o_rdwr o_trunc +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (3 of 26): open/trunc/create +@@ +$1/open_test $2/ls2 o_rdwr o_trunc o_creat +event_count 1 +event[0] truncate +-------------------------------------------- +@@ Standard i/o tests (4 of 26): open/create +@@ +$1/open_test $2/ls3 o_rdwr o_creat +event_count 1 +event[0] read +-------------------------------------------- +@@ Standard i/o tests (5 of 26): new file +@@ +$1/open_test $2/LS3 o_rdwr o_creat +event_count 2 +event[0] create +event[1] postcreate +-------------------------------------------- +@@ Standard i/o tests (6 of 26): append #1 +@@ +echo j >> $2/ls4 +event_count 1 +event[0] write +file_handle[0] store_in ls4temp +-------------------------------------------- +@@ Standard i/o tests (7 of 26): append #2 +@@ +echo j >> $2/ls4 +event_count 1 +event[0] write +file_handle[0] matches ls4temp +-------------------------------------------- +@@ Standard i/o tests (8 of 26): remove +@@ +/bin/rm $2/ls4 +event_count 3 +event[0] remove +event[1] destroy +event[2] postremove +name[1] test +contents[1] 123456789abcdefghijklmnopqrstuvwxyz +-------------------------------------------- +@@ Standard i/o tests (9 of 26): link +@@ +ln $2/ls5 $2/LS5 +event_count 2 +event[0] link +event[1] postlink +-------------------------------------------- +@@ Standard i/o tests (10 of 26): deleting link +@@ +/bin/rm $2/LS5 +event_count 2 +event[0] remove +event[1] postremove +-------------------------------------------- +@@ Standard i/o tests (11 of 26): return_on_destroy #1 +@@ +run_without_test +$1/set_return_on_destroy $real_dir +-------------------------------------------- +@@ Standard i/o tests (12 of 26): return_on_destroy #2 +@@ +/bin/rm $2/ls5 +event_count 3 +event[0] remove +event[1] destroy +event[2] postremove +name[1] +contents[1] +-------------------------------------------- +@@ Standard i/o tests (13 of 26) +@@ +$1/fcntl f_freesp -o 99999 -l 199999 $2/ls6 +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (14 of 26) +@@ +$1/fcntl f_freesp -o 1000 -l 10000 $2/ls6 +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (15 of 26) truncate #1 +@@ +$1/truncate $2/ls7 99999 +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (16 of 26) truncate #2 +@@ +$1/truncate $2/ls7 1000 +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (17 of 26) execute +@@ +$2/ls8 -l $real_dir +event[0] read +event[1] read +event[2] read +event[3] read +event[4] read +offset[0] 0 +length[0] 29604 +file_handle[0] matches file_handle[1] +file_handle[0] matches file_handle[2] +file_handle[0] matches file_handle[3] +-------------------------------------------- +@@ Standard i/o tests (18 of 26) symlink +@@ +ln -s $2/junk $2/symlink +event_count 2 +event[0] symlink +event[1] postsymlink +-------------------------------------------- +@@ Standard i/o tests (19 of 26) deleting symlink +@@ +/bin/rm $2/symlink +event_count 3 +event[0] remove +event[1] destroy +event[2] postremove +-------------------------------------------- +@@ Standard i/o tests (20 of 26) mkdir +@@ +mkdir $2/unlikely-named-test-dir +event_count 2 +event[0] create +event[1] postcreate +-------------------------------------------- +@@ Standard i/o tests (21 of 26) rmdir +@@ +rmdir $2/unlikely-named-test-dir +event_count 3 +event[0] remove +event[1] destroy +event[2] postremove +-------------------------------------------- +@@ Standard i/o tests (22 of 26) rename +@@ +mv $2/ls8 $2/LS8 +event_count 2 +event[0] rename +event[1] postrename +-------------------------------------------- +@@ Standard i/o tests (23 of 26) copy (new) +@@ +cp $2/ls9 $2/LS9 +event_count 9 +event[0] create +event[1] postcreate +event[2] attribute +event[3] read +event[4] read +event[5] read +event[6] read +event[7] read +event[8] attribute +-------------------------------------------- +@@ Standard i/o tests (24 of 26) copy (onto old) +@@ +cp $2/LS9 $2/ls9 +event_count 5 +event[0] truncate +event[1] write +event[2] write +event[3] write +event[4] write +-------------------------------------------- +@@ Standard i/o tests (25 of 26) memory-mapped i/o +@@ +// Note to self: don't check event_count +// +cc -o $2/ll0 $2/ctest.c +event[0] truncate +event[1] write +event[2] attribute +event[3] read +event[4] write +-------------------------------------------- +@@ Standard i/o tests (26 of 26) executing +@@ +$2/ll0 +event[0] read +event[1] read +event[2] read +event[3] read +event[4] read diff --git a/dmapi/src/suite2/data/standard_nfs.dat b/dmapi/src/suite2/data/standard_nfs.dat new file mode 100644 index 000000000..8acf3f933 --- /dev/null +++ b/dmapi/src/suite2/data/standard_nfs.dat @@ -0,0 +1,247 @@ +// +// Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of version 2 of the GNU General Public License as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it would be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// Further, this software is distributed without any warranty that it is +// free of the rightful claim of any third person regarding infringement +// or the like. Any license provided herein, whether implied or +// otherwise, applies only to this software file. Patent licenses, if +// any, provided herein do not apply to combinations of this program with +// other software, or any other product whatsoever. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write the Free Software Foundation, Inc., 59 +// Temple Place - Suite 330, Boston MA 02111-1307, USA. +// +// Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +// Mountain View, CA 94043, or: +// +// http://www.sgi.com +// +// For further information regarding this notice, see: +// +// http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + +// This test will use the following files: +// +ctf stf ls_to_copy ctest.c +fcntl open_test truncate rd wf +read_invis write_invis +set_region set_return_on_destroy +-------------------------------------------- +// These setup commands are run before the daemon starts. +// They reset the file structure of the test directory +// to a known state. +// +rm $real_dir/??? +$1/ctf $1 $real_dir +$1/stf $1 $real_dir/l?? +rm $real_dir/ctest.c +cp $1/ctest.c $real_dir +chown $lname $real_dir/l?? +chown $lname $real_dir/ctest.c +$1/set_return_on_destroy $real_dir test +-------------------------------------------- +@@ Standard i/o tests (1 of 26): open +@@ +$1/open_test $2/ls0 o_rdwr +event_count 1 +event[0] read +-------------------------------------------- +@@ Standard i/o tests (2 of 26): open/trunc +@@ +$1/open_test $2/ls1 o_rdwr o_trunc +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (3 of 26): open/trunc/create +@@ +$1/open_test $2/ls2 o_rdwr o_trunc o_creat +event_count 1 +event[0] truncate +-------------------------------------------- +@@ Standard i/o tests (4 of 26): open/create +@@ +$1/open_test $2/ls3 o_rdwr o_creat +event_count 1 +event[0] read +-------------------------------------------- +@@ Standard i/o tests (5 of 26): new file +@@ +$1/open_test $2/LS3 o_rdwr o_creat +event_count 2 +event[0] create +event[1] postcreate +-------------------------------------------- +@@ Standard i/o tests (6 of 26): append #1 +@@ +echo j >> $2/ls4 +event_count 2 +event[0] read +event[1] write +file_handle[0] store_in ls4temp +-------------------------------------------- +@@ Standard i/o tests (7 of 26): append #2 +@@ +echo j >> $2/ls4 +event_count 1 +event[0] write +file_handle[0] matches ls4temp +-------------------------------------------- +@@ Standard i/o tests (8 of 26): remove +@@ +/bin/rm $2/ls4 +event_count 3 +event[0] remove +event[1] destroy +event[2] postremove +name[1] test +contents[1] 123456789abcdefghijklmnopqrstuvwxyz +-------------------------------------------- +@@ Standard i/o tests (9 of 26): link +@@ +ln $2/ls5 $2/LS5 +event_count 2 +event[0] link +event[1] postlink +-------------------------------------------- +@@ Standard i/o tests (10 of 26): deleting link +@@ +/bin/rm $2/LS5 +event_count 2 +event[0] remove +event[1] postremove +-------------------------------------------- +@@ Standard i/o tests (11 of 26): return_on_destroy #1 +@@ +run_without_test +$1/set_return_on_destroy $real_dir +-------------------------------------------- +@@ Standard i/o tests (12 of 26): return_on_destroy #2 +@@ +/bin/rm $2/ls5 +event_count 3 +event[0] remove +event[1] destroy +event[2] postremove +name[1] +contents[1] +-------------------------------------------- +@@ Standard i/o tests (13 of 26) +@@ +$1/fcntl f_freesp -o 99999 -l 199999 $2/ls6 +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (14 of 26) +@@ +$1/fcntl f_freesp -o 1000 -l 10000 $2/ls6 +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (15 of 26) truncate #1 +@@ +$1/truncate $2/ls7 99999 +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (16 of 26) truncate #2 +@@ +$1/truncate $2/ls7 1000 +event_count 2 +event[0] truncate +event[1] attribute +-------------------------------------------- +@@ Standard i/o tests (17 of 26) execute +@@ +$2/ls8 -l $real_dir +event_count 4 +event[0] read +event[1] read +event[2] read +event[3] read +-------------------------------------------- +@@ Standard i/o tests (18 of 26) symlink +@@ +ln -s $2/junk $2/symlink +event_count 2 +event[0] symlink +event[1] postsymlink +-------------------------------------------- +@@ Standard i/o tests (19 of 26) deleting symlink +@@ +/bin/rm $2/symlink +event_count 3 +event[0] remove +event[1] destroy +event[2] postremove +-------------------------------------------- +@@ Standard i/o tests (20 of 26) mkdir +@@ +mkdir $2/unlikely-named-test-dir +event_count 2 +event[0] create +event[1] postcreate +-------------------------------------------- +@@ Standard i/o tests (21 of 26) rmdir +@@ +rmdir $2/unlikely-named-test-dir +event_count 3 +event[0] remove +event[1] destroy +event[2] postremove +-------------------------------------------- +@@ Standard i/o tests (22 of 26) rename +@@ +mv $2/ls8 $2/LS8 +event_count 2 +event[0] rename +event[1] postrename +-------------------------------------------- +@@ Standard i/o tests (23 of 26) copy (new) +@@ +cp $2/ls9 $2/LS9 +event_count 8 +event[0] create +event[1] postcreate +event[2] attribute +event[3] read +event[4] read +event[5] read +event[6] read +event[7] attribute +-------------------------------------------- +@@ Standard i/o tests (24 of 26) copy (onto old) +@@ +cp $2/LS9 $2/ls9 +event_count 5 +event[0] truncate +event[1] write +event[2] write +event[3] write +event[4] write +-------------------------------------------- +@@ Standard i/o tests (25 of 26) memory-mapped i/o +@@ +// Note to self: don't check event_count +// +cc -o $2/ll0 $2/ctest.c +event[0] truncate +event[1] attribute +event[2] write +-------------------------------------------- +@@ Standard i/o tests (26 of 26) executing +@@ +$2/ll0 +event_count 0 diff --git a/dmapi/src/suite2/dist/README b/dmapi/src/suite2/dist/README new file mode 100644 index 000000000..49aca8f84 --- /dev/null +++ b/dmapi/src/suite2/dist/README @@ -0,0 +1,463 @@ +# +# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + + DMAPI Test Suite + Informational File + ------------------ + +I) Getting Started + + A) Extracting from DMAPI_test.cpio + + 1) Create a new directory for storing the tests. We will refer to + this as the "base" directory. The base directory can be + located anywhere; it does NOT need to be in a DMAPI filesystem. + + 2) Move the archive file DMAPI_test.cpio to the base directory + and execute the following command to extract from the archive: + + cat DMAPI_test.cpio | cpio -icd + + 3) There should now be several files and subdirectories in the base + directory, including the file "file_list". Read this file for a + complete listing of which files should be present in which + directories. Compare "file_list" with the output of "ls -Rpl" + to be sure that you have the necessary files. + + 4) The base directory contains the files and programs that are of + immediate use for testing. The "bindir" subdirectory contains + the test programs and datafiles. The "lib" and "src" subdirectories + contain C libraries and source code for the C programs. + + B) Checking the Existence and Version of DMAPI + + The program check_dmapi can verify that you have the correct + version of DMAPI installed. Note: it can only be run as root. + Execute this command (from the "base" directory): + + bindir/check_dmapi + + It should report that you have a current version of DMAPI. If it + does not, it will also suggest which components of your DMAPI are + not current, and where to find a patch to update them. + + C) Configuration + + 1) Creating the Test Directories + + a) The Test Filesystem + + Mount a DMAPI filesystem, or use an existing one. + This filesystem's mount info MUST be listed in /etc/fstab. + + Write down the path to this filesystem's mountpoint, and label + it as "m_main" for future use. + + b) The Main Test Directory + + Create a new directory in the "m_main" filesystem. + + Write down the path to this directory. Note ONLY the part + that comes AFTER "m_main". Label this as "d_name". + + EXAMPLE: You have a DMAPI filesystem /dmi_main + You name the test directory /dmi_main/test_dir + "m_main" is /dmi_main + "d_name" is /test_dir + + c) The Cross-NFS Test Directories + + For NFS tests, all you must do is create two empty directories + (one for nfs2, one for nfs3). They do NOT need to be in a + DMAPI filesystem. + + Your main test directory will be mounted across NFS, into these + two directories. Normally, the tests will do this automatically. + However, if you need to do this mount manually, the command + would look like this example: + + mount -t nfs2 localhost:/dmi_main /dmi_nfs2 + + Write down the paths to these nfs2 and nfs3 test directories. + Label them "m_nfs2" and "m_nfs3" respectively. + + c) The Realtime Test Filesystem and Directory + + If you wish to test realtime i/o, you'll need a filesystem + mounted with a realtime partition, and a directory in that + filesystem. + + Label the path to the filesystem mountpoint as "m_rt". + Label the path to the test directory as "d_rt". + + 2) Configuring menu_test + + The Korn-shell script named menu_test is an interface to the + other test programs. At the beginning of the script, there + is a "configuration section", in which is sets several variables + for use in the rest of the script. + + Open menu_test in any text editor and change the following + variable assignments in the configuration section: + + a) base_dir: + Set this to the pathname of your "base" directory + (where you un-archived "DMAPI_test.cpio"). + + b) p_user: + Tests that do not run as root will run as this "primary" user. + Set this to any username. + + c) m_main: + The mountpoint of the main test filesystem. + Set this to the value of "m_main" that you wrote down above. + + d) d_name: + m_main concatenated with d_name is the main test directory path. + Set this to the value for "d_name" that you wrote down above. + + e) m_nfs2: + The mountpoint of the nfs2 test filesystem. + Set this to the value of "m_nfs2" that you wrote down above. + + f) m_nfs2: + The mountpoint of the nfs3 test filesystem. + Set this to the value of "m_nfs3" that you wrote down above. + + g) m_rt: + The mountpoint of the realtime test filesystem. + Set this to the value of "m_rt" that you wrote down above. + + h) d_rt: + The path to the realtime test directory. + Set this to the value of "d_rt" that you wrote down above. + + 3) Configuring "DMAPI_aliases" + + This is an optional alternative to the menu interface. It runs + as a Korn shell "dot" script and creates an alias to each test. + It was made for those who wish to run tests directly from the + command line. + + DMAPI_aliases has exactly the same configuration section as + menu_test. If you wish to use DMAPI_aliases, make the same + changes to its configuration section. + +II) Running the Tests + + A) Using "menu_test" to run tests + + 1) You must be superuser, using the Korn shell, to run menu_test. + You also must have adjusted the variables in menu_test's + "configuration section", as was explained above. + + 2) menu_test is (surprise!) menu based. Choose options by entering + their numbers. + + 3) The names of the menu options explain which DMAPI functions + or DMAPI events are being tested. Some of the options, labeled + accordingly, run more than one test programs. + + 4) See section SECTION# for a list of the test scripts and programs, + and a brief explanation of each script or program's function. + + B) Using "DMAPI_aliases" to run tests + + 1) NOTE: The aliases in DMAPI_aliases are meant to be used by + those who are familiar with the test programs and wish to run + them more directly. [Designer's note: I included the alias + file more out of nostalgia than necessity.] + + 2) You should be superuser, using the Korn shell, to run DMAPI_aliases. + You also must have adjusted the variables in DMAPI_aliases's + "configuration section", as was explained above. + + 3) DMAPI_aliases should be invoked as a Korn shell "dot" script: + + . ./DMAPI_aliases + + It sets an alias for each test program; each alias begins with + the characters "do_" and is followed by some appropriate name. + Read DMAPI_aliases, or execute "alias | grep do", to + + C) Running tests directly + + 1) For the VERY adventurous, all the tests in the "bindir" directory + can be run directly from the command line. Only some of the files + in "bindir" are test scripts/programs. Read section III for a list + of function tests and section IV for a list of run_test (.dat) + testfiles. + + 2) Running a test program without parameters will produce a list of + correct options. (The exception to this is check_dmapi, which + normally has no parameters. check_dmapi takes only one option, + [-v] for verbose output.) + + 3) It is suggested that you read a program's source before running + it directly. (The source of the C programs is included in the + "src" directory.) Specificually, in each source file, an initial + comment explains the program's options/parameters in detail. + +III) DMAPI Function tests: + + This section offers a terse description of the DMAPI function tests. + For those tests written in C, the source code is given in the "src" + directory. The ksh scripts can, of course, be read directly. + In all cases except check_dmapi, running the program without + parameters will produce a list of correct options. + + A) check_dmapi + Written in: C + Test of: presence (and correct version) of DMAPI library and kernel. + Options: [-v] flag for verbose output. + + B) test_dmattr + Written in: C + Test of: dm_get_dmattr, dm_set_dmattr, dm_remove_dmattr. + + C) test_efault + Written in: C + Test of: various bad function calls that should generate EFAULT, + according to the DMAPI specification. + + D) test_eventlist + Written in: C + Test of: dm_get_eventlist, dm_set_eventlist. + + E) test_fileattr + Written in: C + Test of: dm_get_fileattr, dm_set_fileattr, + dm_get_dirattrs, dm_get_bulkattr. + + F) test_hole + Written in: C + Test of: dm_probe_hole, dm_punch_hole. + + G) test_invis + Written in: C + Test of: dm_read_invis, dm_write_invis. + + H) test_region + Written in: C + Test of: dm_get_region, dm_set,region. + + I) test_rights + Written in: C + Test of: various bad function calls that should generate EACCES, + and other conditions pertaining to DMAPI rights. + + J) test_allocinfo_1 + Written in: ksh + Test of: dm_get_allocinfo. + + K) test_allocinfo_2 + Written in: ksh + Test of: dm_get_allocinfo. + +IV) DMAPI Event tests and the "run_test" ksh script + + A) How to use the "run_test" script + + 1) A quick description of run_test's behavior: + run_test invokes a DMAPI daemon (as a ksh coprocess). It then + reads a "testfile", which contains a description of the test. + + 2) You must be superuser, using the Korn shell, to execute run_test. + + 3) Executing run_test without parameters will produce a list of + correct options. For a much more in-depth explanation of the + options to run_test, read its own initial comment. + + B) The existing .dat testfiles + + 1) fail.dat + 2) main.dat + 3) nfs.dat + 4) old_nfs3.dat + 5) pending.dat + 6) pending_nfs.dat + 7) realtime.dat + 8) smallq.dat + 9) standard.dat + 10) standard_nfs.dat + + C) How to write ".dat" testfiles + + 1) Overview + + A testfile contains a complete description of a DMAPI event test. + Testfiles are divided into sections: the first two contain + test initialization, while the remaining sections each contain ONE + command, followed by a list of expected events. + + The following is a description of testfile syntax. If you wish to + fully understand testfile syntax, PLEASE examine the existing + testfiles and the "run_test" script. + + 2) Event information variables + + a) From the daemon, "run_test" gets information about DMAPI events. + This information is stored in event information variables. + + b) NOTE: event information variables are not persistant. + After "run_test" has compared the expected and actual events + for a command, and before it executes the next command, it + unsets the values of all these variables. + + c) Most of these variables are arrays, indexed by the number of + the event (starting with 0). For example, if the initial event + is a read event, then we have "event[0]" set to "read", and + "file_handle[0]" set to the handle of whatever file was read. + + d) "event_count" is a special variable. It holds the number of + events that were generated by the most recent command. + + e) These are all the event information variables: + + contents event event_count fs_handle handle length + offset media_designator mode mountpoint_handle + mountpoint_path msg_str name new_name new_parent + parent_handle ret_code root_handle sequence token + tries_left unmount_mode + + f) PLEASE examine the run_test script to see which variables + are set by which events. (The scheme corresponds, roughly, + to the "Event Types" section of the DMAPI specification.) + + 3) Testfile section 1: List of required files + + a) A testfile's first section is a list of the files it requires. + If these files are not present in the "bindir" directory, + "run_test" will abort the test and inform the user of which + files are missing. + + b) Each line of this section may contain ANY NUMBER of filenames. + + c) Lines beginning with // will be treated as comments. The + entirety of such lines will be ignored. + + d) The last line of this section should begin with three hyphens + --- Other characters on that line will be ignored. + + 4) Testfile section 2: Initialization commands + + a) A testfile's second section consists of a list of commands. + "run_test" will execute these commands before starting the + DMAPI daemon. Any necessary initialization should be done + here. + + b) Each line of this section should be ONE shell command. + + c) Lines beginning with // will be treated as comments. + The entirety of such lines will be ignored. + + d) The last line of this section should begin with three hyphens + "---" Other characters on that line will be ignored. + + 5) Testfile sections 3 and on: Individual tests + + a) The remaining sections of a testfile consist of a single + shell command, followed by descriptions of events that should + be generated by the command. + + b) Comments + + 1) Comments are valid ONLY before the command. + + 2) Lines beginning with // will be treated as comments. + The entirety of such lines will be ignored. + + 3) Lines beginning with @@ will be treated as "print" comments. + Such lines will not be parsed, but they will be printed to + standard output during the test. This is useful for + describing what each test does. + + c) Valid grammar for the command itself + + 1) Standard command syntax: + This should be ONE shell command, on a line by itself. + + 2) Alternate command syntax: + + A) run_as_root: + If the test is preceeded by the metacommand "run_as_root" + (on a line by itself) then the command will be run as + root rather than as "p_user". The command should still + be one command on a line by itself. + + B) run_without_test: + If the test is preceeded by the metacommand + "run_without_test" (on a line by itself), then ALL + subsequent lines in the section will be executed as + commands, and NO testing will be performed. Note that + the commands will be executed as root. This is useful + for re-initialization sections during a test. + + d) Valid grammar for the "expected events" lines + + 1) [variable_name] [value] + This specifies that the variable [variable_name] should be + set to [value]. + + 2) [variable_name_1] matches [variable_name_2] + This specifies that both variables should be set to + the same value. A list of valid variables + + 3) [variable_name] store_in [string] + This specifies that the contents of [variable_name] + should be stored in a variable named [string]. + The variable [string] can then be referenced as a + variable in later tests. + + EXAMPLE: if two commands deal with the file "foobar", + you might want to check that they both use the same handle. + In the first section, write + "handle[0] store_in old_handle_0" + In the second section, write + "old_handle_0 matches handle[0]" + + 4) failure + This specifies that the command is expected to fail + (return some non-zero exit status). If "failure" + is not specified, the command is expected to succeed. + + e) The last line of these sections should begin with three + hyphens "---". Other characters on that line will be ignored. + + 6) Sending messages to the DMAPI daemon + + + 7) Other "helper functions" for testfiles + + + + + diff --git a/dmapi/src/suite2/lib/errtest.h b/dmapi/src/suite2/lib/errtest.h new file mode 100644 index 000000000..0c1f19a05 --- /dev/null +++ b/dmapi/src/suite2/lib/errtest.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +#ifndef __ERRTEST_SEEN +#define __ERRTEST_SEEN + +#include +#include +#include +#include + +#define NUM_ERRS 100 + +void* handle_clone(void* src_hanp, u_int hlen ); + +char * +errno_names[] = { + "ERROR_0", + "EPERM", + "ENOENT", + "ESRCH", + "EINTR", + "EIO", + "ENXIO", + "E2BIG", + "ENOEXEC", + "EBADF", + "ECHILD", + "EAGAIN", + "ENOMEM", + "EACCES", + "EFAULT", + "ENOTBLK", + "EBUSY", + "EEXIST", + "EXDEV", + "ENODEV", + "ENOTDIR", + "EISDIR", + "EINVAL", + "ENFILE", + "EMFILE", + "ENOTTY", + "ETXTBSY", + "EFBIG", + "ENOSPC", + "ESPIPE", + "EROFS", + "EMLINK", + "EPIPE", + "EDOM", + "ERANGE", + "ENOMSG", + "EIDRM", + "ECHRNG", + "EL2NSYNC", + "EL3HLT", + "EL3RST", + "ELNRNG", + "EUNATCH", + "ENOCSI", + "EL2HLT", + "EDEADLK", + "ENOLCK", + "ERROR_47", + "ERROR_48", + "ERROR_49", + "EBADE", + "EBADR", + "EXFULL", + "ENOANO", + "EBADRQC", + "EBADSLT", + "EDEADLOCK", + "EBFONT", + "ERROR_58", + "ERROR_59", + "ENOSTR", + "ENODATA", + "ETIME", + "ENOSR", + "ENONET", + "ENOPKG", + "EREMOTE", + "ENOLINK", + "EADV", + "ESRMNT", + "ECOMM", + "EPROTO", + "ERROR_72", + "ERROR_73", + "EMULTIHOP", + "ERROR_75", + "ERROR_76", + "EBADMSG", + "ENAMETOOLONG", + "EOVERFLOW", + "ENOTUNIQ", + "EBADFD", + "EREMCHG", + "ELIBACC", + "ELIBBAD", + "ELIBSCN", + "ELIBMAX", + "ELIBEXEC", + "EILSEQ", + "ENOSYS", + "ELOOP", + "ERESTART", + "ESTRPIPE", + "ENOTEMPTY", + "EUSERS", + "ENOTSOCK", + "EDESTADDRREQ", + "EMSGSIZE", + "EPROTOTYPE", + "ENOPROTOOPT" }; + +#define ERR_NAME \ + ((errno +#include +#ifdef linux +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- +Automated test of version of DMAPI libraries & kernels + +The command line is: + + check_dmapi [-v] + +where v is a verbose-output flag +----------------------------------------------------------------------------*/ +#ifdef linux +#define CREATE_DESTROY_OPCODE DM_DESTROY_SESSION +#define SET_DISP_OPCODE DM_SET_DISP +#else +#define CREATE_DESTROY_OPCODE 5 +#define SET_DISP_OPCODE 46 +#endif + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + +char *Progname; + +int dmi(int, ...); + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-v]\n" + "\t(use the v switch for verbose output)\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t old_sid = -1; + dm_sessid_t sid; + void *hanp; + size_t hlen; + dm_token_t token = DM_NO_TOKEN; + int Vflag = 0; + char *name = "old"; + char *junk = "test junk"; + int opt; + int i; + int kernel_status=-1; + int library_status=-1L; + dm_size_t retval; + struct stat stat_buf; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "v")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case '?': + usage(); + } + } + if (optind != argc) + usage(); + + + if (geteuid()!=0) { + printf("You are running as user #%d. " + "You must be root to run this diagnostic.\n", geteuid()); + exit(1); + } + + /*-------------------------------- + * EXAMINE /usr/include/sys/dmi.h: + *-------------------------------- + */ +#ifdef linux +#define DMAPI_HDR "/usr/include/linux/dmapi.h" +#else +#define DMAPI_HDR "/usr/include/sys/dmi.h" +#endif + if (stat(DMAPI_HDR, &stat_buf)==-1){ + if (errno==ENOENT) { + printf( "You are missing a vital DMAPI file: %s\n", DMAPI_HDR); + } + else { + printf( "ERROR: could not stat %s (%s)\n", DMAPI_HDR, strerror(errno)); + } + } + else { + if (stat_buf.st_size <= 15000) { + printf("You appear to have an old version of a vital DMAPI file: %s\n", DMAPI_HDR); + } + else if (Vflag) { + printf("(You appear to have the correct version of %s\n", DMAPI_HDR); + } + } + + /*-------------------------- + * RESOLVE KERNEL PRESENCE: + *-------------------------- + */ + if (dmi(CREATE_DESTROY_OPCODE, old_sid, junk, &sid) >= 0) { + printf("ERROR: invalid kernel create/destroy_session call " + "succeeded!\n"); + exit(1); + } + else if (errno==ENOPKG) { + kernel_status=0; + } + else if (errno==EINVAL){ + if (Vflag) printf("(create/destroy_session call verifies " + "that you have DMAPI in kernel)\n"); + } + else { + printf("ERROR: kernel create/destroy_session call produced " + "unexpected errno, (%d) %s\n", errno, strerror(errno)); + } + + /*---------------------------------- + * RESOLVE KERNEL STATUS IF PRESENT: + *---------------------------------- + */ + if (kernel_status==-1 && + dmi(SET_DISP_OPCODE, + (dm_sessid_t) 0, + (void*) 0, + (size_t) 0, + (dm_token_t) 0, + (dm_eventset_t) 0, + (u_int) 0) >= 0) { + printf("ERROR: invalid kernel set_disp call suceeded!\n"); + } + else { + if (errno==ENOSYS) { + if (Vflag) + printf("(kernel set_disp call indicates old kernel)\n"); + kernel_status=1; + } + else if (errno==ENOPKG) { + if (Vflag) + printf("(kernel set_disp call indicates no kernel)\n"); + kernel_status=0; + } + else if (errno==EINVAL) { + if (Vflag) + printf("(kernel set_disp call indicates new kernel)\n"); + kernel_status=2; + } + else { + printf("ERROR: kernel set_disp call failed: (%d) %s\n", + errno, strerror(errno)); +/* XXX */ +/* exit(1);*/ + } + } + + /*------------------------- + * RESOLVE LIBRARY STATUS: + *------------------------- + */ + if (dm_init_service(&name) == -1) { + fprintf(stderr, "ERROR: can't inititalize the DMAPI (%s).\n", + strerror(errno)); + library_status=0; + } + else if (strcmp(name, DM_VER_STR_CONTENTS)) { + if (Vflag) + printf("(dm_init_service suggests that " + "you have an old library)\n"); + library_status=1; + } + else { + if (Vflag) + printf("(dm_init_service suggests that " + "you have a new library)\n"); + library_status=2; + } + + if (Vflag) printf("(dm_init_service returned %s)\n", name); + + /*------------------------- + * MAKE A DIAGNOSIS: + *------------------------- + */ + + if (library_status==2 && kernel_status==2){ + printf("DIAGNOSIS: Tests show a current version of " + "DMAPI is installed.\n"); + } + else if (library_status==1 && kernel_status==1) { + printf("DIAGNOSIS: Tests show that you have an outdated " + "installation of DMAPI.\nUpgrades to both kernel and " + "library routines will be necessary.\n"); + } + else if (library_status==0 && kernel_status==0) { + printf("DIAGNOSIS: Tests show that NO components of the DMAPI " + "are installed!\nUpgrades to both kernel and " + "library routines will be necessary.\n"); + } + else { + printf("DIAGNOSIS: Tests show that:\n" + "Your DMAPI kernel routines are "); + switch (kernel_status) { + case 0: printf ("missing (not installed).\n"); + break; + case 1: printf ("outdated.\n"); + break; + case 2: printf ("current.\n "); + break; + default: printf("[ERROR!].\n"); + } + printf("Your DMAPI library is "); + switch (library_status) { + case 0: printf ("missing (not installed).\n"); + break; + case 1: printf ("outdated.\n"); + break; + case 2: printf ("current.\n"); + break; + default: printf("[ERROR!].\n"); + } + } +#ifndef linux + if (library_status!=2 || kernel_status!=2){ + printf("Please install XFS patch 1907 (for IRIX 6.2) or " + "patch 2287 (for IRIX 6.4).\n"); + } +#endif +} + + + diff --git a/dmapi/src/suite2/src/dm_test_daemon.c b/dmapi/src/suite2/src/dm_test_daemon.c new file mode 100644 index 000000000..d26be9f87 --- /dev/null +++ b/dmapi/src/suite2/src/dm_test_daemon.c @@ -0,0 +1,1328 @@ + + +/* + * dm_test_daemon.c + * + * Joseph Jackson + * 25-Jun-1996 + * + * Additions: + * Jay Woodward + * 6-Aug-1997 + * + * Monitor all events for a file system. + * When one arrives, print a message with all the details. + * If the message is synchronous, always reply with DM_RESP_CONTINUE + * (This program doesn't perform any real file system or HSM work.) + * + * This is a simplification of the "migin.c" example program. + * The original code was by Peter Lawthers: + * This code was written by Peter Lawthers, and placed in the public + * domain for use by DMAPI implementors and app writers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef linux +#define MAXNAMELEN 256 +#endif + + /* + * Define some standard formats for the printf statements below. + */ + +#define HDR "%s\ntoken :%d\nsequence :%d\n" +#define VALS "%-15s:%s\n" +#define VALD "%-15s:%d\n" +#ifdef __sgi +#define VALLLD "%-15s:%lld\n" +#else +#define VALLLD "%-15s:%ld\n" +#endif + +extern int optind; +extern int errno; + +void usage (char *); +int main (int, char **); +static void event_loop (dm_sessid_t, int); +int handle_message (dm_sessid_t, dm_eventmsg_t *); +static int format_mode(mode_t mode, char **ptr); +static int get_fs_handle (char *, void **, size_t *); +static int set_disposition(dm_sessid_t, void *, size_t); +static int set_events (dm_sessid_t, void *, size_t); +static int clear_events (dm_sessid_t, void *, size_t); +int finish_responding(dm_sessid_t); +int establish_handler(void); +void exit_handler (void); + +/* + * Keep these global so the exit_handler and err_msg routines can get to them + */ +char *Progname; +int Sleep = 0; +int Verbose; +dm_sessid_t sid = 0; +dm_sessid_t oldsid = 0; +char *fsname; +int friendly=1; +int unfriendly_errno=EBADMSG; +int unfriendly_count=0; +int pending_count=0; +int token_arr[10]; +int arr_top=0; + +void +usage( + char *prog) +{ + fprintf(stderr, "Usage: %s ", prog); + fprintf(stderr, "<-s sleeptime> <-S oldsid> <-v verbose> "); + fprintf(stderr, "filesystem \n"); +} + + +int +main( + int argc, + char *argv[]) +{ + + int c; + int error; + void *fs_hanp; + size_t fs_hlen; + char buf[BUFSIZ + 8]; + + Progname = argv[0]; + fsname = NULL; + + while ((c = getopt(argc, argv, "vs:S:")) != EOF) { + switch (c) { + case 's': + Sleep = atoi(optarg); + break; + case 'S': + oldsid = atoi(optarg); + break; + case 'v': + Verbose = 1; + break; + case '?': + default: + usage(Progname); + exit(1); + } + } + if (optind >= argc) { + usage(Progname); + exit(1); + } + fsname = argv[optind]; + if (fsname == NULL) { + usage(Progname); + exit(1); + } + + /* + * Establish an exit handler + */ + error = establish_handler(); + if (error) + exit(1); + + /* + * Init the dmapi, and get a filesystem handle so + * we can set up our events + */ + + if (oldsid) { + sid = oldsid; + } else { + error = setup_dmapi(&sid); + if (error) + exit(1); + } + + error = get_fs_handle(fsname, &fs_hanp, &fs_hlen); + if (error) + goto cleanup; + + /* + * Set the event disposition so that our session will receive + * all the events for the given file system + */ + error = set_disposition(sid, fs_hanp, fs_hlen); + if (error) + goto cleanup; + + /* + * Enable monitoring for all events in the given file system + */ + error = set_events(sid, fs_hanp, fs_hlen); + if (error) + goto cleanup; + + /* + * Set line buffering!! + */ + error = setvbuf(stdout, buf, _IOLBF, BUFSIZ); + if (error) + goto cleanup; + + /* + * Now sit in an infinite loop, reporting on any events that occur. + * The program is exited after a signal through exit_handler(). + */ + printf("\n"); + event_loop(sid, 1 /*waitflag*/); + + /* + * If we get here, cleanup after the event_loop failure + */ + cleanup: + exit_handler(); + return(1); +} + + +/* + * Main event loop processing + * + * The waitflag argument is set to 1 when we call this from main(). + * In this case, continuously process incoming events, + * blocking if there are none available. + * In the exit_handler(), call this routine with waitflag=0. + * Just try to read the events once in this case with no blocking. + */ + +static void +event_loop( + dm_sessid_t sid, + int waitflag) +{ + void *msgbuf; + size_t bufsize; + int error; + dm_eventmsg_t *msg; + int count; + + /* + * We take a swag at a buffer size. If it's wrong, we can + * always resize it + */ + + bufsize = sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + HANDLE_LEN; + bufsize *= 50; + msgbuf = (void *)malloc(bufsize); + if (msgbuf == NULL) { + err_msg("Can't allocate memory for buffer"); + return; + } + + for (;;) { + error = dm_get_events(sid, ALL_AVAIL_MSGS, + waitflag ? DM_EV_WAIT:0, bufsize, msgbuf, &bufsize); + if (error) { + if (errno == EAGAIN) { + if (waitflag) + continue; + break; + } + if (errno == E2BIG) { + free(msgbuf); + msgbuf = (void *)malloc(bufsize); + if (msgbuf == NULL) { + err_msg("Can't resize msg buffer"); + return; + } + continue; + } + errno_msg("Error getting events from DMAPI"); + break; + } + + /* + * Walk through the message buffer, pull out each individual + * message, and dispatch the messages to handle_message(), + * which will respond to the events. + */ + + count = 0; + msg = (dm_eventmsg_t *)msgbuf; + while (msg != NULL ) { + count++; + error = handle_message(sid, msg); + if (error) { + free(msgbuf); + return; + } + printf("end_of_message\n"); + msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *); + } + if (count != 1 && Verbose) { + err_msg("Found %d events in one call to " + "dm_get_events\n", count); + } + } + if (msgbuf != NULL) + free(msgbuf); +} + + +void +print_one_mount_event( + void *msg) +{ + void *hanp1, *hanp2, *hanp3; + size_t hlen1, hlen2, hlen3; + char hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR]; + void *namp1, *namp2; + size_t nlen1, nlen2; + char nams1[MAXNAMELEN], nams2[MAXNAMELEN]; + mode_t mode; + +#if VERITAS + dm_namesp_event_t *msg_ne = (dm_namesp_event_t *)msg; + + msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *); + hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *); + hlen1 = DM_GET_LEN (msg_ne, ne_handle1); + hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *); + hlen2 = DM_GET_LEN (msg_ne, ne_handle2); + namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *); + nlen1 = DM_GET_LEN (msg_ne, ne_name1); + namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *); + nlen2 = DM_GET_LEN (msg_ne, ne_name2); + rootp = NULL; + rlen = 0; + mode = msg_ne->ne_mode; +#else + dm_mount_event_t *msg_me = (dm_mount_event_t *)msg; + + hanp1 = DM_GET_VALUE(msg_me, me_handle1, void *); + hlen1 = DM_GET_LEN(msg_me, me_handle1); + hanp2 = DM_GET_VALUE(msg_me, me_handle2, void *); + hlen2 = DM_GET_LEN(msg_me, me_handle2); + namp1 = DM_GET_VALUE(msg_me, me_name1, void *); + nlen1 = DM_GET_LEN(msg_me, me_name1); + namp2 = DM_GET_VALUE(msg_me, me_name2, void *); + nlen2 = DM_GET_LEN(msg_me, me_name2); + hanp3 = DM_GET_VALUE(msg_me, me_roothandle, void *); + hlen3 = DM_GET_LEN(msg_me, me_roothandle); + mode = msg_me->me_mode; +#endif /* VERITAS */ + + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } else { + sprintf(hans1, "", hlen1); + } + if (hanp2 && hlen2) { + hantoa(hanp2, hlen2, hans2); + } else { + sprintf(hans2, "", hlen2); + } + if (hanp3 && hlen3) { + hantoa(hanp3, hlen3, hans3); + } else { + sprintf(hans3, "", hlen3); + } + if (namp1 && nlen1) { + strncpy(nams1, namp1, nlen1); + if (nlen1 != sizeof(nams1)) + nams1[nlen1] = '\0'; + } else { + sprintf(nams1, "", nlen1); + } + if (namp2 && nlen2) { + strncpy(nams2, namp2, nlen2); + if (nlen2 != sizeof(nams2)) + nams2[nlen2] = '\0'; + } else { + sprintf(nams2, "", nlen2); + } + + printf(VALS VALS VALS VALS VALS VALD, + "fs handle", hans1, + "mtpt handle", hans2, + "mtpt path", nams1, + "media desig", nams2, + "root handle", hans3, + "mode", mode); +} + + +/* + * First, weed out the events which return interesting structures. + * If it's not one of those, unpack the dm_namesp_event structure + * and display the contents. + */ +int +handle_message( + dm_sessid_t sid, + dm_eventmsg_t *msg) +{ + int pkt_error = 0; + int error; + int respond, response, respcode; + dm_namesp_event_t *msg_ne; +#if !VERITAS + dm_mount_event_t *msg_me; +#endif + void *hanp1, *hanp2, *namp1, *namp2; + u_int hlen1, hlen2, nlen1, nlen2; + char hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR]; + char nams1[MAXNAMELEN], nams2[MAXNAMELEN]; + void *fs_hanp; + size_t fs_hlen; + dm_timestruct_t *pending_time; + + /* + * Set the defaults for responding to events + */ + + /***************************************************** + * If the daemon is feeling unfriendly, it will + * respond (when necessary) with DM_RESP_ABORT, rather + * than the standard DM_RESP_CONTINUE. + * + * While unfriendly, the daemon normally returns + * a respcode of "unfriendly_errno". This defaults to + * EBADMSG but can be set when unfriendly mode is + * activated. + *****************************************************/ + + respond = 1; + if (unfriendly_count==0) { + response = friendly ? DM_RESP_CONTINUE : DM_RESP_ABORT; + respcode = friendly ? 0 : unfriendly_errno; + } + else if (unfriendly_count > 0) { + if (unfriendly_count-- == 0) { + response = DM_RESP_CONTINUE; + respcode = 0; + } + else { + response = DM_RESP_ABORT; + respcode = unfriendly_errno; + } + } + + if (pending_count >= 0) { + if (msg->ev_type != DM_EVENT_USER) { + if (pending_count-- == 0) { + int i; + for (i=arr_top; i>=0; --i) { + dm_respond_event(sid, token_arr[i], + DM_RESP_CONTINUE, 0, 0, 0); + } + response = DM_RESP_CONTINUE; + respcode = 0; + } + else { + if (pending_count<10) { + token_arr[pending_count]=msg->ev_token; + } + pending_time = malloc(sizeof(dm_timestruct_t)); + pending_time->dm_tv_sec=0; + pending_time->dm_tv_nsec=0; + dm_pending(sid, msg->ev_token, pending_time); + printf("pending\ntries left\t:%d\n",pending_count); + return 0; + } + } + } + + /***** USER EVENTS *****/ + + if (msg->ev_type == DM_EVENT_USER) { + char *privp; + u_int plen, i; + + printf(HDR, + "user", msg->ev_token, msg->ev_sequence); + + /* print private data as ascii or hex if it exists + DM_CONFIG_MAX_MESSAGE_DATA */ + + privp = DM_GET_VALUE(msg, ev_data, char *); + plen = DM_GET_LEN (msg, ev_data); + if (plen) { + for (i = 0; i < plen; i++) { + if (!isprint(privp[i]) && !isspace(privp[i])) + break; + } + if (i == plen - 1 && privp[i] == '\0') { + /***************************************************** + * Here, we check the messages from send_message. + * Some of them have special meanings. + *****************************************************/ + if (strncmp(privp, "over", 4)==0) { + response = DM_RESP_CONTINUE; + respcode = 0; + } + else if (strncmp(privp, "pending", 7)==0){ + if (strlen(privp)>8) { + sscanf(privp, "pending%*c%d", &pending_count); + } + else { + pending_count=1; + } + arr_top=pending_count-1; + } + else if (strncmp(privp, "reset_fs", 8)==0){ + if (get_fs_handle(fsname, &fs_hanp, &fs_hlen)){ + strcpy(privp, "error"); + } + else if (set_disposition(sid, fs_hanp, fs_hlen)){ + strcpy(privp, "error"); + } + else if (set_events(sid, fs_hanp, fs_hlen)){ + strcpy(privp, "error"); + } + } + else if (strncmp(privp, "friendly", 8)==0) { + friendly = 1; + response = DM_RESP_CONTINUE; + respcode = 0; + } + else if (strncmp(privp, "unfriendly", 10)==0) { + friendly = 0; + response = DM_RESP_CONTINUE; + respcode = 0; + if (strlen(privp)>11) { + sscanf(privp, "unfriendly%*c%d", &unfriendly_errno); + } + else { + unfriendly_errno=EBADMSG; + } + } + else if (strncmp(privp, "countdown", 9)==0) { + response = DM_RESP_CONTINUE; + respcode = 0; + + if (strlen(privp)>10) { + sscanf(privp, "countdown%*c%d%*c%d", + &unfriendly_count, &unfriendly_errno); + } + else { + unfriendly_count=5; + unfriendly_errno=EAGAIN; + } + } + + + printf(VALS, + "privdata", privp); + + } else { + printf("privdata :"); + for (i = 0; i < plen; i++) { + printf("%.2x", privp[i]); + } + printf("\n"); + } + } else { + printf(VALS, + "privdata", ""); + } + + if (msg->ev_token == DM_INVALID_TOKEN) /* async dm_send_msg event */ + respond = 0; + } + + /***** CANCEL EVENT *****/ + +/* Not implemented on SGI or Veritas */ + + else if (msg->ev_type == DM_EVENT_CANCEL) { + dm_cancel_event_t *msg_ce; + + msg_ce = DM_GET_VALUE(msg, ev_data, dm_cancel_event_t *); + printf(HDR VALD VALD, + "cancel", msg->ev_token, msg->ev_sequence, + "sequence", msg_ce->ce_sequence, + "token", msg_ce->ce_token); + respond = 0; + } + + /***** DATA EVENTS *****/ + + else if (msg->ev_type == DM_EVENT_READ || + msg->ev_type == DM_EVENT_WRITE || + msg->ev_type == DM_EVENT_TRUNCATE) { + dm_data_event_t *msg_de; + + msg_de = DM_GET_VALUE(msg, ev_data, dm_data_event_t *); + hanp1 = DM_GET_VALUE(msg_de, de_handle, void *); + hlen1 = DM_GET_LEN (msg_de, de_handle); + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } else { + sprintf(hans1, "", hlen1); + } + + switch(msg->ev_type) { + + case DM_EVENT_READ: + printf(HDR VALS VALLLD VALLLD, + "read", msg->ev_token, msg->ev_sequence, + "file handle", hans1, + "offset", msg_de->de_offset, + "length", msg_de->de_length); + break; + + case DM_EVENT_WRITE: + printf(HDR VALS VALLLD VALLLD, + "write", msg->ev_token, msg->ev_sequence, + "file handle", hans1, + "offset", msg_de->de_offset, + "length", msg_de->de_length); + break; + + case DM_EVENT_TRUNCATE: + printf(HDR VALS VALLLD VALLLD, + "truncate", msg->ev_token, msg->ev_sequence, + "file handle", hans1, + "offset", msg_de->de_offset, + "length", msg_de->de_length); + break; + } + } + + /***** DESTROY EVENT *****/ + + else if (msg->ev_type == DM_EVENT_DESTROY) { + dm_destroy_event_t *msg_ds; + char attrname[DM_ATTR_NAME_SIZE + 1]; + u_char *copy; + u_int clen; + u_int i; + + msg_ds= DM_GET_VALUE(msg, ev_data, dm_destroy_event_t *); + hanp1 = DM_GET_VALUE(msg_ds, ds_handle, void *); + hlen1 = DM_GET_LEN (msg_ds, ds_handle); + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } else { + sprintf(hans1, "", hlen1); + } + if (msg_ds->ds_attrname.an_chars[0] != '\0') { + strncpy(attrname, (char *)msg_ds->ds_attrname.an_chars, sizeof(attrname)); + } else { + strcpy(attrname, ""); + } + printf(HDR VALS VALS, + "destroy", msg->ev_token, msg->ev_sequence, + "handle", hans1, + "attrname", attrname); + copy = DM_GET_VALUE(msg_ds, ds_attrcopy, u_char *); + clen = DM_GET_LEN (msg_ds, ds_attrcopy); + if (copy && clen) { + printf("attrcopy :"); + for (i = 0; i < clen; i++) { + /* Old version: printf("%.2x", copy[i]); */ + printf("%c", copy[i]); + } + printf("\n"); + } else { + printf(VALS, "attrcopy", ""); + } + respond = 0; + } + + /***** MOUNT EVENT *****/ + + else if (msg->ev_type == DM_EVENT_MOUNT) { + printf(HDR, "mount", msg->ev_token, msg->ev_sequence); +#if !VERITAS + msg_me = DM_GET_VALUE(msg, ev_data, dm_mount_event_t *); + print_one_mount_event(msg_me); +#else /* VERITAS */ + msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *); + print_one_mount_event(msg_ne); +#endif /* VERITAS */ + } + + /***** NAMESPACE EVENTS *****/ + + else { + char *type; + + msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *); + hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *); + hlen1 = DM_GET_LEN (msg_ne, ne_handle1); + hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *); + hlen2 = DM_GET_LEN (msg_ne, ne_handle2); + namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *); + nlen1 = DM_GET_LEN (msg_ne, ne_name1); + namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *); + nlen2 = DM_GET_LEN (msg_ne, ne_name2); + + if (hanp1 && hlen1) { + hantoa(hanp1, hlen1, hans1); + } + if (hanp2 && hlen2) { + hantoa(hanp2, hlen2, hans2); + } + if (namp1 && nlen1) { + strncpy(nams1, namp1, nlen1); + if (nlen1 != sizeof(nams1)) + nams1[nlen1] = '\0'; + } + if (namp2 && nlen2) { + strncpy(nams2, namp2, nlen2); + if (nlen2 != sizeof(nams2)) + nams2[nlen2] = '\0'; + } + + if (msg->ev_type == DM_EVENT_PREUNMOUNT || + msg->ev_type == DM_EVENT_UNMOUNT) { + if (msg_ne->ne_mode == 0) { + type = "NOFORCE"; +#if !VERITAS + } else if (msg_ne->ne_mode == DM_UNMOUNT_FORCE) { +#else + } else if (msg_ne->ne_mode > 0) { +#endif + type = "FORCE"; + } else { + type = "UNKNOWN"; + pkt_error++; + } + } else if (msg->ev_type == DM_EVENT_CREATE || + msg->ev_type == DM_EVENT_POSTCREATE || + msg->ev_type == DM_EVENT_REMOVE || + msg->ev_type == DM_EVENT_POSTREMOVE) { + if (format_mode(msg_ne->ne_mode, &type)) { + pkt_error++; + } + } + + switch(msg->ev_type) { + + case DM_EVENT_PREUNMOUNT: + printf(HDR VALS VALS VALS, + "preunmount", msg->ev_token, msg->ev_sequence, + "fs handle", hans1, + "root dir", hans2, + "unmount mode", type); + break; + + case DM_EVENT_UNMOUNT: + printf(HDR VALS VALS VALD, + "unmount", msg->ev_token, msg->ev_sequence, + "fs handle", hans1, + "unmount mode", type, + "retcode", msg_ne->ne_retcode); + break; + + case DM_EVENT_NOSPACE: + printf(HDR VALS, + "nospace", msg->ev_token, msg->ev_sequence, + "fs handle", hans1); + response = DM_RESP_ABORT; + respcode = ENOSPC; + break; + + case DM_EVENT_DEBUT: /* not supported on SGI */ + printf(HDR VALS, + "debut", msg->ev_token, msg->ev_sequence, + "object", hans1); + break; + + case DM_EVENT_CREATE: + printf(HDR VALS VALS VALS, + "create", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "mode bits", type); + break; + + case DM_EVENT_POSTCREATE: + printf(HDR VALS VALS VALS VALS VALD, + "postcreate", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "new object", hans2, + "name", nams1, + "mode bits", type, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_REMOVE: + printf(HDR VALS VALS VALS, + "remove", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "mode bits", type); + break; + + case DM_EVENT_POSTREMOVE: + printf(HDR VALS VALS VALS VALD, + "postremove", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "mode bits", type, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_RENAME: + printf(HDR VALS VALS VALS VALS, + "rename", msg->ev_token, msg->ev_sequence, + "old parent", hans1, + "new parent", hans2, + "old name", nams1, + "new name", nams2); + break; + + case DM_EVENT_POSTRENAME: + printf(HDR VALS VALS VALS VALS VALD, + "postrename", msg->ev_token, msg->ev_sequence, + "old parent", hans1, + "new parent", hans2, + "old name", nams1, + "new name", nams2, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_SYMLINK: + printf(HDR VALS VALS VALS, + "symlink", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "name", nams1, + "contents", nams2); + break; + + case DM_EVENT_POSTSYMLINK: + printf(HDR VALS VALS VALS VALS VALD, + "postsymlink", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "new object", hans2, + "name", nams1, + "contents", nams2, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_LINK: + printf(HDR VALS VALS VALS, + "link", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "source", hans2, + "name", nams1); + break; + + case DM_EVENT_POSTLINK: + printf(HDR VALS VALS VALS VALD, + "postlink", msg->ev_token, msg->ev_sequence, + "parent dir", hans1, + "source", hans2, + "name", nams1, + "retcode", msg_ne->ne_retcode); + respond = 0; + break; + + case DM_EVENT_ATTRIBUTE: + printf(HDR VALS, + "attribute", msg->ev_token, msg->ev_sequence, + "object", hans1); + respond = 0; + break; + + case DM_EVENT_CLOSE: /* not supported on SGI */ + printf(HDR VALS, + "close", msg->ev_token, msg->ev_sequence, + "object", hans1); + respond = 0; + break; + + default: + pkt_error++; + printf(HDR VALD, + "", msg->ev_token, msg->ev_sequence, + "ev_type", msg->ev_type); + if (msg->ev_token == DM_INVALID_TOKEN) + respond = 0; + break; + } + } + + /* + * Now respond to those messages which require a response + */ + if (respond) { + if (Sleep) sleep(Sleep); /* Slow things down here */ + + error = dm_respond_event(sid, msg->ev_token, response, respcode, 0, 0); + if (error) { + errno_msg("Can't respond to event"); + return error; + } + } + + return 0; +} + + +/* + Convert a mode_t field into a printable string. + + Returns non-zero if the mode_t is invalid. The string is + returned in *ptr, whether there is an error or not. +*/ + +static int +format_mode( + mode_t mode, + char **ptr) +{ +static char modestr[100]; + char *typestr; + int error = 0; + + if (S_ISFIFO(mode)) typestr = "FIFO"; + else if(S_ISCHR (mode)) typestr = "Character Device"; + else if(S_ISBLK (mode)) typestr = "Block Device"; + else if(S_ISDIR (mode)) typestr = "Directory"; + else if(S_ISREG (mode)) typestr = "Regular File"; + else if(S_ISLNK (mode)) typestr = "Symbolic Link"; + else if(S_ISSOCK(mode)) typestr = "Socket"; + else { + typestr = ""; + error++; + } + + sprintf(modestr, "mode %06o (perm %c%c%c %c%c%c %c%c%c %c%c%c) " + "type %s", + mode, + mode & S_ISUID ? 's':' ', + mode & S_ISGID ? 'g':' ', + mode & S_ISVTX ? 't':' ', + mode & S_IRUSR ? 'r':'-', + mode & S_IWUSR ? 'w':'-', + mode & S_IXUSR ? 'x':'-', + mode & S_IRGRP ? 'r':'-', + mode & S_IWGRP ? 'w':'-', + mode & S_IXGRP ? 'x':'-', + mode & S_IROTH ? 'r':'-', + mode & S_IWOTH ? 'w':'-', + mode & S_IXOTH ? 'x':'-', + typestr); + *ptr = modestr; + return(error); +} + + +static int +get_fs_handle( + char *fsname, + void **fs_hanpp, + size_t *fs_hlenp) +{ + char hans[HANDLE_STR]; + + if (dm_path_to_fshandle(fsname, fs_hanpp, fs_hlenp) == -1) { + errno_msg("Can't get filesystem handle"); + return 1; + } + if (Verbose) { + hantoa(*fs_hanpp, *fs_hlenp, hans); + err_msg("File system handle for %s: %s\n", fsname, hans); + } + return 0; +} + + +/* + Set the event disposition for this filesystem to include all valid + DMAPI events so that we receive all events for this filesystem. + Also set DM_EVENT_MOUNT disposition for the global handle. + It does not make sense to specify DM_EVENT_USER in the disposition + mask since a session is always unconditionally registered for these + events. + + Returns non-zero on error. +*/ + +static int +set_disposition( + dm_sessid_t sid, + void *fs_hanp, + size_t fs_hlen) +{ + dm_eventset_t eventlist; + + if (Verbose) { + err_msg("Setting event disposition to send all " + "events to this session\n"); + } + + /* DM_EVENT_MOUNT must be sent in a separate request using the global + handle. If we ever support more than one filesystem at a time, this + request should be moved out of this routine to a place where it is + issued just once. + */ + + DMEV_ZERO(eventlist); + DMEV_SET(DM_EVENT_MOUNT, eventlist); + + if (dm_set_disp(sid, DM_GLOBAL_HANP, DM_GLOBAL_HLEN, DM_NO_TOKEN, + &eventlist, DM_EVENT_MAX) == -1) { + errno_msg("Can't set event disposition for mount"); + return(1); + } + + DMEV_ZERO(eventlist); + + /* File system administration events. */ + + DMEV_SET(DM_EVENT_PREUNMOUNT, eventlist); + DMEV_SET(DM_EVENT_UNMOUNT, eventlist); + DMEV_SET(DM_EVENT_NOSPACE, eventlist); + + /* While DM_EVENT_DEBUT is optional, it appears that the spec always + lets it be specified in a dm_set_disp call; its just that the + event will never be seen on some platforms. + */ + + DMEV_SET(DM_EVENT_DEBUT, eventlist); + + + /* Namespace events. */ + + DMEV_SET(DM_EVENT_CREATE, eventlist); + DMEV_SET(DM_EVENT_POSTCREATE, eventlist); + DMEV_SET(DM_EVENT_REMOVE, eventlist); + DMEV_SET(DM_EVENT_POSTREMOVE, eventlist); + DMEV_SET(DM_EVENT_RENAME, eventlist); + DMEV_SET(DM_EVENT_POSTRENAME, eventlist); + DMEV_SET(DM_EVENT_LINK, eventlist); + DMEV_SET(DM_EVENT_POSTLINK, eventlist); + DMEV_SET(DM_EVENT_SYMLINK, eventlist); + DMEV_SET(DM_EVENT_POSTSYMLINK, eventlist); + + /* Managed region data events. */ + + DMEV_SET(DM_EVENT_READ, eventlist); + DMEV_SET(DM_EVENT_WRITE, eventlist); + DMEV_SET(DM_EVENT_TRUNCATE, eventlist); + + /* Metadata events. */ + + DMEV_SET(DM_EVENT_ATTRIBUTE, eventlist); +#if ! defined ( __sgi ) && ! defined ( VERITAS ) + DMEV_SET(DM_EVENT_CANCEL, eventlist); /* not supported on SGI */ +#endif +#ifndef __sgi + DMEV_SET(DM_EVENT_CLOSE, eventlist); /* not supported on SGI */ +#endif + DMEV_SET(DM_EVENT_DESTROY, eventlist); + + /* Pseudo-events. */ + + /* DM_EVENT_USER - always enabled - causes EINVAL if specified */ + + if (dm_set_disp(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, + &eventlist, DM_EVENT_MAX) == -1) { + errno_msg("Can't set event disposition for filesystem"); + return(1); + } + return(0); +} + + +/* + Enable event generation on each valid filesystem-based DMAPI event + within the given file system. + + Returns non-zero on errors. +*/ + +static int +set_events( + dm_sessid_t sid, + void *fs_hanp, + size_t fs_hlen) +{ + dm_eventset_t eventlist; + + if (Verbose) { + err_msg("Setting event list to enable all events " + "for this file system\n"); + } + DMEV_ZERO(eventlist); + + /* File system administration events. */ + + /* DM_EVENT_MOUNT - always enabled on the global handle - causes + EINVAL if specified. + */ + DMEV_SET(DM_EVENT_PREUNMOUNT, eventlist); + DMEV_SET(DM_EVENT_UNMOUNT, eventlist); + DMEV_SET(DM_EVENT_NOSPACE, eventlist); + /* DM_EVENT_DEBUT - always enabled - causes EINVAL if specified. */ + + /* Namespace events. */ + + DMEV_SET(DM_EVENT_CREATE, eventlist); + DMEV_SET(DM_EVENT_POSTCREATE, eventlist); + DMEV_SET(DM_EVENT_REMOVE, eventlist); + DMEV_SET(DM_EVENT_POSTREMOVE, eventlist); + DMEV_SET(DM_EVENT_RENAME, eventlist); + DMEV_SET(DM_EVENT_POSTRENAME, eventlist); + DMEV_SET(DM_EVENT_LINK, eventlist); + DMEV_SET(DM_EVENT_POSTLINK, eventlist); + DMEV_SET(DM_EVENT_SYMLINK, eventlist); + DMEV_SET(DM_EVENT_POSTSYMLINK, eventlist); + + /* Managed region data events. These are not settable by + dm_set_eventlist on a filesystem basis. They are meant + to be set using dm_set_region on regular files only. + However, in the SGI implementation, they are filesystem-settable. + Since this is useful for testing purposes, do it. + */ + + /* DM_EVENT_READ */ + /* DM_EVENT_WRITE */ + /* DM_EVENT_TRUNCATE */ + + /* Metadata events. */ + + DMEV_SET(DM_EVENT_ATTRIBUTE, eventlist); +#if ! defined ( __sgi ) && ! defined ( VERITAS ) + DMEV_SET(DM_EVENT_CANCEL, eventlist); /* not supported on SGI */ +#endif +#ifndef __sgi + DMEV_SET(DM_EVENT_CLOSE, eventlist); /* not supported on SGI */ +#endif + DMEV_SET(DM_EVENT_DESTROY, eventlist); + + /* Pseudo-events. */ + + /* DM_EVENT_USER - always enabled - causes EINVAL if specified */ + + if (dm_set_eventlist(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, + &eventlist, DM_EVENT_MAX) == -1) { + errno_msg("Can't set event list"); + return(1); + } + return(0); +} + + +/* + Disable monitoring for all events in the DMAPI for the given + file system. This is done before exiting so that future + operations won't hang waiting for their events to be handled. + + Returns non-zero on errors. +*/ + +static int +clear_events( + dm_sessid_t sid, + void *fs_hanp, + size_t fs_hlen) +{ + dm_eventset_t eventlist; + + if (Verbose) { + err_msg("Clearing event list to disable all events " + "for this filesystem\n"); + } + DMEV_ZERO(eventlist); + + if (dm_set_eventlist(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, + &eventlist, DM_EVENT_MAX) == -1) { + errno_msg("Can't clear event list"); + return(1); + } + return(0); +} + + +/* + * Respond to any events which haven't been handled yet. + * dm_getall_tokens provides a list of tokens for the outstanding events. + * dm_find_eventmsg uses the token to lookup the corresponding message. + * The message is passed to handle_message() for normal response processing. + */ +int +finish_responding( + dm_sessid_t sid) +{ + int error = 0; + u_int nbytes, ntokens = 0, ret_ntokens, i; + dm_token_t *tokenbuf = NULL; + size_t buflen, ret_buflen; + char *msgbuf = NULL; + dm_eventmsg_t *msg; + + if (Verbose) + err_msg("Responding to any outstanding delivered event messages\n"); + + /* + * Initial sizes for the token and message buffers + */ + ret_buflen = 16 * (sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + + HANDLE_LEN); + ret_ntokens = 16; + + /* + * The E2BIG dance... + * Take a guess at how large to make the buffer, starting with ret_ntokens. + * If the routine returns E2BIG, use the returned size and try again. + * If we're already using the returned size, double it and try again. + */ + do { + ntokens = (ntokens != ret_ntokens) ? ret_ntokens : ntokens*2; + nbytes = ntokens * (sizeof(dm_token_t) + sizeof(dm_vardata_t)); + tokenbuf = malloc(nbytes); + if (tokenbuf == NULL) { + err_msg("Can't malloc %d bytes for tokenbuf\n", nbytes); + error = 1; + goto out; + } + error = dm_getall_tokens(sid, ntokens, tokenbuf, &ret_ntokens); + } while (error && errno == E2BIG); + + if (error) { + errno_msg("Can't get all outstanding tokens"); + goto out; + } + + for (i = 0; i < ret_ntokens; i++) { + if (Verbose) + err_msg("Responding to outstanding event for token %d\n",(int)*tokenbuf); + + /* + * The E2BIG dance reprise... + */ + do { + buflen = (buflen != ret_buflen) ? ret_buflen : buflen * 2; + msgbuf = malloc(buflen); + if (msgbuf == NULL) { + err_msg("Can't malloc %d bytes for msgbuf\n", buflen); + error = 1; + goto out; + } + error = dm_find_eventmsg(sid, *tokenbuf, buflen, msgbuf, &ret_buflen); + } while (error && errno == E2BIG); + if (error) { + errno_msg("Can't find the event message for token %d", (int)*tokenbuf); + goto out; + } + + msg = (dm_eventmsg_t *) msgbuf; + while (msg != NULL) { + error = handle_message(sid, msg); + if (error) + goto out; + msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *); + } + + tokenbuf++; + } + + out: + if (tokenbuf) + free(tokenbuf); + if (msgbuf) + free(msgbuf); + return error; +} + + +/* + * Establish an exit handler since we run in an infinite loop + */ +int +establish_handler(void) +{ + struct sigaction act; + + /* + * Set up signals so that we can wait for spawned children + */ + act.sa_handler = exit_handler; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + + (void)sigaction(SIGHUP, &act, NULL); + (void)sigaction(SIGINT, &act, NULL); + (void)sigaction(SIGQUIT, &act, NULL); + (void)sigaction(SIGTERM, &act, NULL); + (void)sigaction(SIGUSR1, &act, NULL); + (void)sigaction(SIGUSR1, &act, NULL); + (void)sigaction(SIGUSR2, &act, NULL); + + return(0); +} + + +/* + * Exit gracefully + * + * Stop events from being generated for the given file system + * Respond to any events that were delivered but unanswered + * (the event loop may have been in the middle of taking care of the event) + * Try getting any undelivered events but don't block if none are there + * (the file system may have generated an event after we killed dm_get_events) + * Shutdown the session using the global "sid" variable. + */ +void +exit_handler(void) +{ + int error; + void *fs_hanp; + size_t fs_hlen; + + if (Verbose) + printf("\n"), + err_msg("Exiting...\n"); + + error = get_fs_handle(fsname, &fs_hanp, &fs_hlen); + + if (!error) { + error = clear_events(sid, fs_hanp, fs_hlen); + if (error) + /* just keep going */ ; + } + + error = finish_responding(sid); + if (error) + /* just keep going */ ; + + err_msg("Processing any undelivered event messages\n"); + event_loop(sid, 0 /*waitflag*/); + + err_msg("Shutting down the session\n"); + if (sid != 0) { + error = dm_destroy_session(sid); + if (error == -1) { + errno_msg("Can't shut down session - use 'mrmean -kv' to clean up!"); + } + } + + exit(0); +} diff --git a/dmapi/src/suite2/src/dump_allocinfo.c b/dmapi/src/suite2/src/dump_allocinfo.c new file mode 100644 index 000000000..529c5d435 --- /dev/null +++ b/dmapi/src/suite2/src/dump_allocinfo.c @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_get_allocinfo(). The +command line is: + + dump_allocinfo [-D] [-n nelem] [-o offp] [-s sid] pathname + +where pathname is the name of a file, 'offp' is a byte offset from the +beginning of the file where you want to start dumping, and 'nelem' allows +you to specify how many extent structures to use in each dm_get_allocinfo +call. + +The code checks the returned extents as much as possible for errors. +It detects bad ex_type values, verifies that there is always a trailing +hole at the end of the file, that the ex_offset of each extent matches the +ex_offset+ex_length of the previous extent, and that ex_offset+ex_length +is always an even multiple of 512. It verifies that all ex_offset values +after the first fall on a 512-byte boundary. It verifies that the '*offp' +value returned by dm_get_allocinfo() is 0 at the end of the file, and +equals ex_offset+ex_length of the last extent if not at the end of the file. +Any error is reported to stderr, and the program then terminates with a +non-zero exit status. + +The program produces output similar to xfs_bmap in order to make comparison +easier. Here is some sample output. + +f1: offset 1 + rc 0, nelemp 17 + 0: [0..127]: resv [1..511] + +Line 1 gives the name of the file and the byte offset within the file where +the dump started. Line 2 appears once for each dm_get_allocinfo() call, +giving the return value (rc) and the number of extents which were returned. +Line 3 is repeated once for each extent. The first field "0:" is the extent +number. The second field "[0..127]:" give the starting and ending block for +the extent in 512-byte units. The third field is either "resv" to indicate +allocated space or "hole" if the extent is a hole. The fourth field +"[1..511]" only appears if the dump did not start with byte zero of the +first block. In that case, the first number shows the actual byte offset +within the block (1 in this case). The second number should always be +511 since we always dump to the end of a block. + +Possible tests +-------------- + +Run the test scripts "test_allocinfo_1" and "test_allocinfo_2". +(The former compares dump_allocinfo output with xfs_bmap output. The latter +compares various dump_allocinfo outputs, from trials with many different +buffer sizes). + +Produce a file with holes, and perform the following tests using just one +extent (-e 1). + Dump extents from beginning of the file. + Dump from byte 1 of the file. + Dump from the last byte of the first extent. + Dump from the first byte of the second extent. + Dump from the middle of the second extent. + Dump the first byte of the last extent. + Dump the last byte of the last extent. + Dump the first byte after the last extent. + Dump starting at an offset way past the end of the file. + +Produce a fragmented file with many adjacent DM_EXTENT_RES extents. + Repeat the above tests. + +Produce a GRIO file with holes. + Repeat the above tests. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + +static int print_alloc(dm_sessid_t sid, void* hanp, size_t hlen, + char *pathname, dm_off_t startoff, u_int nelem); + +char *Progname; +int Dflag = 0; + + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s [-D] [-n nelem] [-o off] [-s sid] " + "pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_off_t startoff = 0; /* starting offset */ + u_int nelem = 100; + char *pathname; + void *hanp; + size_t hlen; + dm_stat_t sbuf; + char *name; + int opt; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Dn:o:s:")) != EOF) { + switch(opt) { + case 'D': + Dflag++; + break; + case 'n': + nelem = atol(optarg); + break; + case 'o': + startoff = atoll(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + pathname = argv[optind]; + + if (dm_init_service(&name)) { + fprintf(stderr, "dm_init_service failed, %s\n", + strerror(errno)); + exit(1); + } + + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the file's handle and verify that it is a regular file. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for %s\n", pathname); + exit(1); + } + if (dm_get_fileattr(sid, hanp, hlen, DM_NO_TOKEN, DM_AT_STAT, &sbuf)) { + fprintf(stderr, "dm_get_fileattr failed\n"); + exit(1); + } + if (!S_ISREG(sbuf.dt_mode)) { + fprintf(stderr, "%s is not a regular file\n", pathname); + exit(1); + } + + /* Print the allocation. */ + + if (print_alloc(sid, hanp, hlen, pathname, startoff, nelem)) + exit(1); + + dm_handle_free(hanp, hlen); + exit(0); +} + + +static int +print_alloc( + dm_sessid_t sid, + void *hanp, + size_t hlen, + char *pathname, + dm_off_t startoff, + u_int nelem) +{ + dm_off_t endoff; + dm_extent_t *extent; + u_int nelemp; + u_int num = 0; + u_int i; + char *type = NULL; + int rc; + + if (Dflag) fprintf(stdout, "%s: starting offset %lld\n", pathname, startoff); + + /* Allocate space for the number of extents requested by the user. */ + + if ((extent = malloc(nelem * sizeof(*extent))) == NULL) { + fprintf(stderr, "can't malloc extent structures\n"); + return(1); + } + + rc = 1; + endoff = startoff; + + while (rc != 0) { + rc = dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, &startoff, + nelem, extent, &nelemp); + if (rc < 0) { + fprintf(stderr, "dm_get_allocinfo failed, %s\n", + strerror(errno)); + return(1); + } + + if (Dflag) fprintf(stdout, "\treturned %d, nelemp %d\n", rc, nelemp); + + if (Dflag && nelemp) + fprintf(stdout, " ex_type ex_offset ex_length\n"); + + /* Note: it is possible for nelemp to be zero! */ + + for (i = 0; i < nelemp; i++) { + /* The extent must either be reserved space or a hole. */ + switch (extent[i].ex_type) { + case DM_EXTENT_RES: + type = "resv"; + break; + case DM_EXTENT_HOLE: + type = "hole"; + break; + default: + fprintf(stderr, "invalid extent type %d\n", + extent[i].ex_type); + return(1); + } + + if (i!=nelemp-1 || rc!=0) { + if (!Dflag) { + fprintf(stdout, "\t%d: [%lld..%lld]: %s", num, + extent[i].ex_offset / 512, + (extent[i].ex_offset + + extent[i].ex_length - 1) / 512, type); + if ((extent[i].ex_offset % 512 != 0) || + (endoff % 512 != 0)) { + fprintf(stdout, "\t[%lld..%lld]\n", + extent[i].ex_offset % 512, + (endoff-1) % 512); + } else { + fprintf(stdout, "\n"); + } + } else { + fprintf(stdout, "%5s %13lld %13lld\n", + type, extent[i].ex_offset, + extent[i].ex_length); + } + } + /* The ex_offset of the first extent should match the + 'startoff' specified by the caller. The ex_offset + in subsequent extents should always match + (ex_offset + ex_length) of the previous extent, + and should always start on a 512 byte boundary. + */ + + if (extent[i].ex_offset != endoff) { + fprintf(stderr, "new extent (%lld)is not " + "adjacent to previous one (%lld)\n", + extent[i].ex_offset, endoff); + return(1); + } + if (num && (extent[i].ex_offset % 512) != 0) { + fprintf(stderr, "non-initial ex_offset (%lld) " + "is not a 512-byte multiple\n", + extent[i].ex_offset); + return(1); + } + + /* Non-initial extents should have ex_length values + that are an even multiple of 512. The initial + extent should be a multiple of 512 less the offset + into the starting 512-byte block. + */ + + if (((extent[i].ex_offset % 512) + extent[i].ex_length) % 512 != 0) { + fprintf(stderr, "ex_length is incorrect based " + "upon the ex_offset\n"); + return(1); + } + + endoff = extent[i].ex_offset + extent[i].ex_length; + num++; /* count of extents printed */ + } + + /* If not yet at end of file, the startoff parameter should + match the ex_offset plus ex_length of the last extent + retrieved. + */ + + if (rc && startoff != endoff) { + fprintf(stderr, "startoff is %lld, should be %lld\n", + startoff, endoff); + return(1); + } + + /* If we are at end of file, the last extent should be a + hole. + */ + + if (!rc && type && strcmp(type, "hole")) { + fprintf(stderr, "file didn't end with a hole\n"); + return(1); + } + } + + /* At end of file, startoff should always equal zero. */ + + if (startoff != 0) { + fprintf(stderr, "startoff was not zero at end of file\n"); + return(1); + } + return(0); +} diff --git a/dmapi/src/suite2/src/invis_test.c b/dmapi/src/suite2/src/invis_test.c new file mode 100644 index 000000000..b4221944d --- /dev/null +++ b/dmapi/src/suite2/src/invis_test.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +#include +#include + +#include + +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +For manually testing DMAPI functions dm_write_invis() and dm_read_invis() + +The command line is: + + invis_test [-Rrv] [-l len] [-o offset] [-s sid] ls_path pathname + +where: + -R + reuse existing test file + -r + use dm_invis_read, default is dm_invis_write. + len + length of read/write + offset + offset in file for read/write + sid + is the session ID whose events you you are interested in. + ls_path + is the path to a specific copy of ls, important only for its size + pathname + is the filesystem to use for the test. + +DM_WRITE_SYNC is is not supported. +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-Rrv] [-l len] [-o offset] [-s sid] ls_path pathname\n", + Progname); + exit(1); +} + +#define BUFSZ 100 + +int +main( + int argc, + char **argv) +{ + int Vflag=0; + dm_sessid_t sid = DM_NO_SESSION; + char *dir_name = NULL; + char *ls_path = NULL; + char *name; + char ch = 'A'; + char test_file[128]; + char command[1024]; + void *hanp; + size_t hlen; + char buf[BUFSZ]; + dm_ssize_t rc; + dm_off_t offset = 0; + dm_size_t length = BUFSZ; + int opt; + int reading = 0; /* writing is the default */ + int exitstat=0; + dm_size_t errblockstart, errblockend; + int in_err_block; + int i; + int reuse_file = 0; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "Rvs:rl:o:")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case 'r': + reading++; + break; + case 'R': + reuse_file++; + break; + case 'l': + length = atoi(optarg); + break; + case 'o': + offset = atoi(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + ls_path = argv[optind]; + dir_name = argv[optind+1]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + sprintf(test_file, "%s/DMAPI_test_file", dir_name); + if( (!reading) && (!reuse_file) ){ + sprintf(command, "cp %s %s\n", ls_path, test_file); + system(command); + } + + if (dm_path_to_handle(test_file, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for %s; bypassing test\n", + test_file); + exit(1); + } + + if( Vflag ) + printf("using length = %lld\n", length ); + if( length > BUFSZ ){ + fprintf(stderr, "length(%lld) > BUFSZ(%lld)\n", length, BUFSZ); + exit(1); + } + + if( reading ){ + memset(buf, '\0', BUFSZ); + + rc = dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN, + offset, length, buf); + if( rc < 0 ){ + fprintf(stderr, "dm_read_invis failed, (err=%d)\n", errno); + dm_handle_free(hanp, hlen); + exit(1); + } + if( rc != length ){ + fprintf(stderr, "dm_read_invis read %lld bytes, wanted to write %lld bytes\n", + rc, length ); + dm_handle_free(hanp, hlen); + exitstat++; + } + else { + printf("dm_read_invis read %lld bytes\n", rc); + } + + in_err_block = 0; + errblockstart = errblockend = 0; + for( i=0; i < length; ++i ){ + if( in_err_block ){ + if( buf[i] != ch ){ + /* still in the err block */ + errblockend = i; + } + else { + /* end of bad block */ + fprintf(stderr, "read err block: byte %lld to %lld\n", errblockstart, errblockend); + in_err_block = 0; + } + } + else if( buf[i] != ch ){ + /* enter err block */ + errblockstart = i; + in_err_block = 1; + } + } + if( in_err_block ){ + /* end of bad block */ + fprintf(stderr, "read err block: byte %lld to %lld\n", errblockstart, errblockend); + in_err_block = 0; + } + } + else { + + memset(buf, ch, BUFSZ); + + rc = dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, + 0, offset, length, buf); + if( rc < 0 ){ + fprintf(stderr, "dm_write_invis failed, (err=%d)\n", errno); + dm_handle_free(hanp, hlen); + exit(1); + } + if( rc != length ){ + fprintf(stderr, "dm_write_invis wrote %lld bytes, wanted to write %lld bytes\n", + rc, length ); + dm_handle_free(hanp, hlen); + exit(1); + } + printf("dm_write_invis wrote %lld bytes\n", rc); + } + + dm_handle_free(hanp, hlen); + exit(exitstat); +} diff --git a/dmapi/src/suite2/src/mm_fill.c b/dmapi/src/suite2/src/mm_fill.c new file mode 100644 index 000000000..25879fe41 --- /dev/null +++ b/dmapi/src/suite2/src/mm_fill.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +/* + * mmap_fill + * + * use memory mapping to fill a filesystem! :) + */ +#include +#include +#include +#include +#include +#include +#include + + +char * progname; +int fd; /* file descriptor */ +addr_t ptr; /* mapped pointers */ +off_t off; +long long junk[512] = { -1 }; +long long counter; + +main(int argc, char * argv[]) +{ + int i; + for (i=0; i<512; i++) junk[i]=-1; + + + if ((progname = strrchr(argv[0], '/')) == NULL) + progname = argv[0]; + else + progname++; + + if (argc < 2) { + fprintf(stderr,"Usage: %s filename\n", progname); + exit(1); + } + + fd = open(argv[1], O_RDWR|O_CREAT, 0644); + if (fd < 0) { + fprintf(stderr,"%s: cannot open %s\n", progname, argv[1]); + perror(argv[1]); + exit(3); + } + + ptr = mmap64(NULL, (size_t)(0x10000000), PROT_WRITE, MAP_SHARED|MAP_AUTOGROW, fd, 0); + if (ptr == MAP_FAILED) { + fprintf(stderr,"%s: cannot mmap64 %s\n", progname, argv[1]); + perror(argv[1]); + exit(3); + } + + for(counter=0; ; counter++) { + junk[0] = counter; + bcopy(junk, ptr, sizeof(junk)); + ptr+=sizeof(junk); + } + printf("%s complete.\n", progname); + return 0; +} diff --git a/dmapi/src/suite2/src/mmap.c b/dmapi/src/suite2/src/mmap.c new file mode 100644 index 000000000..6dc571cf0 --- /dev/null +++ b/dmapi/src/suite2/src/mmap.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +/* + * This routine simulates + * + * cp file1 file2 + * + * + * It is a demo program which does the copy by memory mapping each of the + * files and then doing a byte at a time memory copy. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + + +char * Progname; +off_t len; /* length of file 1 */ +off_t offset = 0; +int print_flags_set = 1; + +typedef struct fflag { + int arg; /* != 0 if ars specified */ + int value; /* flags value */ +} fflag_t; + + +typedef enum ftype { /* flag bit types */ + FL_MAP, FL_PROT, FL_OPEN, FL_MAX +} ftype_t; + +typedef struct mfile { + fflag_t flags[FL_MAX]; + char *path; + int fd; + struct stat st; + addr_t p; +} mfile_t; + + +#define FLAG(symbol,type) { # symbol , symbol, type } +#define MAP_NONE 0 + +static struct { + char *name; + int value; + ftype_t type; +} Flags[] = { + FLAG(O_RDONLY, FL_OPEN), + FLAG(O_WRONLY, FL_OPEN), + FLAG(O_RDWR, FL_OPEN), + FLAG(O_NDELAY, FL_OPEN), + FLAG(O_NONBLOCK, FL_OPEN), + FLAG(O_APPEND, FL_OPEN), + FLAG(O_SYNC, FL_OPEN), + FLAG(O_TRUNC, FL_OPEN), + FLAG(O_CREAT, FL_OPEN), + FLAG(O_DIRECT, FL_OPEN), + FLAG(PROT_NONE, FL_PROT), + FLAG(PROT_READ, FL_PROT), + FLAG(PROT_WRITE, FL_PROT), + FLAG(PROT_EXEC, FL_PROT), + FLAG(PROT_EXECUTE, FL_PROT), + FLAG(MAP_SHARED, FL_MAP), + FLAG(MAP_PRIVATE, FL_MAP), + FLAG(MAP_FIXED, FL_MAP), + FLAG(MAP_RENAME, FL_MAP), + FLAG(MAP_AUTOGROW, FL_MAP), + FLAG(MAP_LOCAL, FL_MAP), + FLAG(MAP_AUTORESRV, FL_MAP), + FLAG(MAP_NONE, FL_MAP), +}; + +int num_Flags = sizeof(Flags)/sizeof(Flags[0]); + + +mfile_t *ifile, *ofile; +mfile_t *hfile; /* Hack job */ +static int hack = 0; + +static mfile_t *new_mfile(void); +static int mfile_opt(char * s, mfile_t * f); +static void print_flags(char *s, mfile_t *f); +static void Usage(void); + +main(int argc, char * argv[]) +{ + int opt; + + if ((Progname = strrchr(argv[0], '/')) == NULL) + Progname = argv[0]; + else + Progname++; + + ifile = new_mfile(); + ofile = new_mfile(); + hfile = new_mfile(); + if (ifile == NULL || ofile == NULL || hfile == NULL) { + fprintf(stderr,"%s: malloc failure.\n", Progname); + exit (1); + } + + /* Set default flags */ + ifile->flags[FL_MAP].value = MAP_PRIVATE; + ifile->flags[FL_PROT].value = PROT_READ; + ifile->flags[FL_OPEN].value = O_RDONLY; + ofile->flags[FL_MAP].value = MAP_SHARED|MAP_AUTOGROW; + ofile->flags[FL_PROT].value = PROT_WRITE; + ofile->flags[FL_OPEN].value = O_RDWR|O_CREAT; + + while ((opt = getopt(argc, argv, "i:o:h:d")) != EOF) { + switch(opt) { + case 'i': + if (mfile_opt(optarg, ifile) != 0) { + fprintf(stderr, "%s: Invalid -i option %s\n", + Progname, optarg); + Usage(); + } + break; + + case 'o': + if (mfile_opt(optarg, ofile) != 0) { + fprintf(stderr, "%s: Invalid -o option %s\n", + Progname, optarg); + Usage(); + } + break; + + case 'h': + if (mfile_opt(optarg, hfile) != 0) { + fprintf(stderr, "%s: Invalid -h option %s\n", + Progname, optarg); + Usage(); + } + hack = 1; + break; + + case 'd': + print_flags_set ^= 1; + break; + case '?': + Usage(); + } + } + + if (optind+1 > argc) + Usage(); + + ifile->path = argv[optind++]; + ofile->path = argv[optind++]; + + if (optind != argc) /* Extra args on command line */ + Usage(); + + if (stat(ifile->path, &(ifile->st)) < 0) { + fprintf(stderr,"%s: stat of %s failed.\n", + Progname, ifile->path); + perror(ifile->path); + exit(2); + } + + len = ifile->st.st_size; + + ifile->fd = open(ifile->path, ifile->flags[FL_OPEN].value); + if (ifile->fd < 0) { + fprintf(stderr,"%s: cannot open %s\n", Progname, ifile->path); + perror(ifile->path); + exit(2); + } + + + ofile->fd = open(ofile->path, ofile->flags[FL_OPEN].value, 0644); + if (ofile->fd < 0) { + fprintf(stderr,"%s: cannot open %s\n", Progname, ofile->path); + perror(ofile->path); + exit(3); + } + + if (print_flags_set) { + print_flags("Input ", ifile); + print_flags("Output", ofile); + if (hack) + print_flags("Hack ", hfile); + } + + + ifile->p = mmap(NULL, len, ifile->flags[FL_PROT].value, + ifile->flags[FL_MAP].value, ifile->fd, 0); + if (ifile->p == MAP_FAILED) { + fprintf(stderr,"%s: cannot mmap %s\n", Progname, ifile->path); + perror(ifile->path); + exit(2); + } + + ofile->p = mmap(NULL, len, ofile->flags[FL_PROT].value, + ofile->flags[FL_MAP].value , ofile->fd, 0); + if (ofile->p == MAP_FAILED) { + fprintf(stderr,"%s: cannot mmap %s\n", Progname, ofile->path); + perror(ofile->path); + exit(3); + } + + if (hack) { + int error; + + error = mprotect(ofile->p, len, hfile->flags[FL_PROT].value); + if (error) { + fprintf(stderr,"%s: mprotect call failed.\n", Progname); + perror("mprotect"); + exit(3); + } + } + + bcopy(ifile->p, ofile->p, len); + + printf("%s complete.\n", Progname); + return 0; +} + +static mfile_t * +new_mfile(void) +{ + mfile_t *ptr = (mfile_t *)malloc(sizeof(*ptr)); + if (ptr) + bzero(ptr, sizeof *ptr); + + return ptr; +} + + +static int +mfile_opt(char * s, mfile_t *f) +{ + int i; + ftype_t type; + + for (i = 0; i < num_Flags; i++) { + if(!strcasecmp(Flags[i].name, s)) { + + /* Zero value if this is 1st arg of this type */ + + type = Flags[i].type; + if (f->flags[type].arg++ == 0) + f->flags[type].value = 0; + f->flags[type].value |= Flags[i].value; + return 0; + } + } + return -1; /* error - string not found */ +} + +static void +Usage(void) +{ + int i; + + fprintf(stderr, + "Usage: %s [-d] [-i flag] [-i flag] [-o flag] ... file1 file2\n", + Progname); + fprintf(stderr, "Valid flag values are:\n"); + + for (i = 0; i < num_Flags; i++) { + fprintf(stderr,"%15s",Flags[i].name); + if ((i+1)%4 == 0 || i == num_Flags-1) + fprintf(stderr,"\n"); + else + fprintf(stderr,","); + } + exit(1); +} + +static void +print_flags(char *s, mfile_t *f) +{ + int i; + ftype_t type; + + printf("DEBUG - %s flags:\n", s); + for (i = 0; i < num_Flags; i++) { + type = Flags[i].type; + if (type == FL_OPEN && Flags[i].value == O_RDONLY && + ((f->flags[type].value) & 3) == 0) + /* Hack to print out O_RDONLY */ + printf("\t%s\n", Flags[i].name); + else if ((Flags[i].value & (f->flags[type].value)) != 0) + printf("\t%s\n", Flags[i].name); + } +} diff --git a/dmapi/src/suite2/src/mmap_cp.c b/dmapi/src/suite2/src/mmap_cp.c new file mode 100644 index 000000000..e695301f7 --- /dev/null +++ b/dmapi/src/suite2/src/mmap_cp.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +/* + * mmap_fill + * + * use memory mapping to fill a filesystem! :) + */ +#include +#include +#include +#include +#include +#include +#include + + +char * progname; +int fd; /* file descriptor */ +addr_t ptr; /* mapped pointers */ +long long junk[512]; + +main(int argc, char * argv[]) +{ + printf("Sizeof junk = %d \n", junk); + exit(0); + + if ((progname = strrchr(argv[0], '/')) == NULL) + progname = argv[0]; + else + progname++; + + if (argc < 2) { + fprintf(stderr,"Usage: %s filename\n", progname); + exit(1); + } + + fd = open(argv[1], O_RDWR|O_CREAT, 0644); + if (fd < 0) { + fprintf(stderr,"%s: cannot open %s\n", progname, argv[1]); + perror(argv[1]); + exit(3); + } + + ptr = mmap(NULL, len, PROT_WRITE, MAP_SHARED|MAP_AUTOGROW , fd, 0); + if (ptr == MAP_FAILED) { + fprintf(stderr,"%s: cannot mmap %s\n", progname, argv[1]); + perror(argv[1]); + exit(3); + } + + while (1) { + bcopy(junk, ptr, size_of(junk)); + ptr+=size_of(junk); + } + printf("%s complete.\n", progname); + return 0; +} diff --git a/dmapi/src/suite2/src/region_test.c b/dmapi/src/suite2/src/region_test.c new file mode 100644 index 000000000..e88c2b415 --- /dev/null +++ b/dmapi/src/suite2/src/region_test.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Manual test for the DMAPI functions dm_set_region() and dm_get_region(). + +The command line is: + + region_test [-Rv] [-s sid] [-l len] [-o offset] ls_path directory + +where + -R + reuse the existing test file + pathname + is the name of a file + ls_path + is the path to a specific copy of ls, important only for its size + sid + is the session ID whose events you you are interested in. +----------------------------------------------------------------------------*/ + +#define NELEM 1 + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-Rv] [-s sid] [-l len] [-o offset] ls_path pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *dir_name = NULL; + char *ls_path = NULL; + char command[1024]; + char test_file[128]; + int opt; + int Vflag = 0; + dm_region_t region = { 0, 0, 0 }; + char *name; + int reuse_file = 0; + void *hanp; + size_t hlen; + dm_boolean_t exactflag; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "vo:l:s:R")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case 'R': + reuse_file++; + break; + case 'o': + region.rg_offset = atol(optarg); + break; + case 'l': + region.rg_size = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 > argc) + usage(); + ls_path = argv[optind]; + dir_name = argv[optind+1]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + sprintf(test_file, "%s/DMAPI_test_file", dir_name); + if( !reuse_file ){ + sprintf(command, "cp %s %s\n", ls_path, test_file); + system(command); + } + + if (dm_path_to_handle(test_file, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", test_file); + exit(1); + } + + region.rg_flags = DM_REGION_READ | DM_REGION_WRITE | DM_REGION_TRUNCATE; + if( dm_set_region( sid, hanp, hlen, DM_NO_TOKEN, NELEM, + ®ion, &exactflag ) ){ + fprintf(stderr, "dm_set_region failed, err=%d\n", errno); + dm_handle_free(hanp,hlen); + exit(1); + } + if( exactflag == DM_FALSE ) + fprintf(stderr, "exact flag was false\n"); + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite2/src/send_msg.c b/dmapi/src/suite2/src/send_msg.c new file mode 100644 index 000000000..3c39247ea --- /dev/null +++ b/dmapi/src/suite2/src/send_msg.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function send_msg(). +The command line is: + + send_msg [-a] [-s sid] string + +where string is the msgdata to be stored in the event. +sid is the session ID to use for the event. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-a] [-s sid] string\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *string; + dm_token_t token; + char *name; + int opt; + int i; + dm_msgtype_t msgtype = DM_MSGTYPE_SYNC; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "as:")) != EOF) { + switch (opt) { + case 'a': + msgtype = DM_MSGTYPE_ASYNC; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 1 != argc) + usage(); + string = argv[optind++]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + if (dm_send_msg(sid, msgtype, strlen(string)+ 1, string)) { + fprintf(stderr, "dm_send_msg failed, %s\n", + strerror(errno)); + exit(1); + } + + exit(0); +} + diff --git a/dmapi/src/suite2/src/test_dmattr.c b/dmapi/src/suite2/src/test_dmattr.c new file mode 100644 index 000000000..f927e190f --- /dev/null +++ b/dmapi/src/suite2/src/test_dmattr.c @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include + +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- +Automated test of the DMAPI functions: + dm_set_dmattr() + dm_get_dmattr() + dm_remove_dmattr() + +The command line is: + + test_dmattr [-v] [-n num] [-l length] [-s sid] directory + +where + ls_path + is the path to a specific copy of ls, important only for its size + directory + is the pathname to a DMAPI filesystem + num + is the number of files to create for the test. + length + is the length of the attribute value for the test. + sid + is the session ID whose attributes you are interested in. + +----------------------------------------------------------------------------*/ + +#define VALUE_LENGTH 22 +#define NUM_ITERATIONS 50 +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-v] [-n number] [-l length] " + "[-s sid] ls_path pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *dir_name; + char *ls_path; + dm_attrname_t *attrnamep; + size_t buflen=VALUE_LENGTH; + char *bufp; + int setdtime = 0; + size_t rlenp; + void *hanp; + size_t hlen; + char *name; + int opt; + int i=0; + int j=0; + int Vflag=0; + int num_iter = NUM_ITERATIONS; + char test_file[128]; + char command[128]; + char **test_array; + dm_size_t config_retval; + dm_token_t test_token; + struct stat *statbuf; + struct stat *checkbuf; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "vn:l:s:")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case 'n': + num_iter = atoi(optarg); + break; + case 'l': + buflen = atoi(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + ls_path = argv[optind]; + dir_name = argv[optind+1]; + + bufp = + (char *)(malloc (buflen * sizeof(char))); + statbuf = + (struct stat *)(malloc (num_iter * sizeof(struct stat))); + checkbuf = + (struct stat *)(malloc (num_iter * sizeof(struct stat))); + test_array = + (char **)(malloc (num_iter * sizeof(char *))); + if (bufp==NULL || test_array==NULL || + statbuf==NULL || checkbuf==NULL) { + printf("Malloc failed\n"); + exit(1); + } + for (i=0; i +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- +Automated search for EFAULT in the following DMAPI commands: + dm_get_allocinfo + dm_get_config + dm_get_config_events + dm_getall_dmattr + dm_init_attrloc + +There are other EFAULT tests, in the programs that test individual +DMAPI functions. Those other tests are referenced in comments in this source. + +The command line is: + test_efault [-s sid] [-v] ls_path pathname + +where: + sid + is the session ID whose events you you are interested in. + ls_path + is the path to a copy of ls, which will be copied as a test file. + pathname + is the filesystem to use for the test. +----------------------------------------------------------------------------*/ + +extern int optind; +extern int opterr; +extern char *optarg; + +char *Progname; +int Vflag=0; + +static void +usage(void) +{ + fprintf(stderr, + "Usage: %s [-v] [-s sid] ls_path pathname\n", + Progname); + exit(1); +} + + +int +main(int argc, char **argv) { + + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t test_token = DM_NO_TOKEN; + void *hanp; + size_t hlen; + char *name; + char *ls_path; + char *pathname; + char test_file[100]; + char command[100]; + int opt; + int i=0; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + opterr = 0; + while ((opt = getopt(argc, argv, "vn:s:")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) { + usage(); + } + ls_path = argv[optind]; + pathname = argv[optind+1]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + printf("Beginning EFAULT testing...\n"); + + /*----------------------------------*\ + |* ## Traditional errno tests ## *| + \*----------------------------------*/ + sprintf(test_file, "%s/DMAPI_EFAULT_test_file", pathname); + sprintf(command, "cp %s %s\n", ls_path, test_file); + system(command); + + if (dm_path_to_handle(test_file, &hanp, &hlen)) { + fprintf(stderr, "ERROR: can't get handle for %s; %s\n", + test_file, ERR_NAME); + goto abort_test; + } + + + /*--------------------------------------------------------- + * get_allocinfo + *--------------------------------------------------------- + */ + { dm_off_t off=0; + u_int nelem=1; + dm_extent_t extent; + dm_extent_t *extentp; + u_int nelem_ret; + + ERRTEST(EFAULT, "get_allocinfo (bad offp)", + dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, + (dm_off_t*)(-1000), + nelem, &extent, &nelem_ret)) + ERRTEST(EFAULT, "get_allocinfo (bad extentp)", + dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, + &off, nelem, (dm_extent_t*)(-1000), + &nelem_ret)) + ERRTEST(EFAULT, "get_allocinfo (bad nelemp)", + dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, + &off, nelem, &extent, + (u_int*)(-1000))) + } + + /*------------------------------------------------------ + * get_bulkattr: see test_fileattr.c + *------------------------------------------------------ + * get_config + *------------------------------------------------------ + */ + ERRTEST(EFAULT, "get_config", + dm_get_config(hanp, hlen, DM_CONFIG_BULKALL, + (dm_size_t*)(-1000))) + /*--------------------------------------------------------- + * get_config_events + *--------------------------------------------------------- + */ + { + u_int nelem=5; + u_int *nelemp; + dm_eventset_t *eventsetp; + eventsetp = (dm_eventset_t *)malloc(nelem*sizeof(dm_eventset_t)); + if (eventsetp == NULL) { + printf("Couldn't malloc for config_events tests: %s\n", ERR_NAME); + } + else { + ERRTEST(EFAULT, "get_config_events (bad eventsetp)", + dm_get_config_events(hanp, hlen, nelem, + (dm_eventset_t*)(-1000), nelemp)) + ERRTEST(EFAULT, "get_config_events (bad nelemp)", + dm_get_config_events(hanp, hlen, nelem, eventsetp, + (u_int*)(-1000))) + } + } + /*--------------------------------------------------------- + * get_dirattrs: see test_fileattr.c + *--------------------------------------------------------- + * get_fileattr: see test_fileattr.c + *--------------------------------------------------------- + * get_region: see test_region.c + *--------------------------------------------------------- + * getall_dmattr + *--------------------------------------------------------- + */ + { + size_t buflen = 5; + void *bufp = (void *)malloc(buflen*sizeof(dm_attrlist_t)); + size_t *rlenp; + ERRTEST(EFAULT, "getall_dmattr (NULL handle)", + dm_getall_dmattr(sid, NULL, hlen, DM_NO_TOKEN, + buflen, bufp, rlenp)) + ERRTEST(EFAULT, "getall_dmattr (incremented bufp)", + dm_getall_dmattr(sid, hanp, hlen, DM_NO_TOKEN, + buflen, (void*)((char*)(bufp)+1), rlenp)) + ERRTEST(EFAULT, "getall_dmattr (bad bufp)", + dm_getall_dmattr(sid, hanp, hlen, DM_NO_TOKEN, + buflen, (void*)(-1000), rlenp)) + ERRTEST(EFAULT, "getall_dmattr (bad rlenp)", + dm_getall_dmattr(sid, hanp, hlen, DM_NO_TOKEN, + buflen, bufp, (size_t*)(-1000))) + } + /*--------------------------------------------------------- + * init_attrloc + *--------------------------------------------------------- + */ + ERRTEST(ENOTSUP, "init_attrloc", + dm_init_attrloc(sid, hanp, hlen, DM_NO_TOKEN, + (dm_attrloc_t*)(-1000))) + /*--------------------------------------------------------- + * probe_hole: see test_hole.c + *--------------------------------------------------------- + * remove_dmattr: see test_dmattr.c + *--------------------------------------------------------- + * set_dmattr: see test_dmattr.c + *--------------------------------------------------------- + * set_eventlist: see test_eventlist.c + *--------------------------------------------------------- + * set_region: see test_region.c + *--------------------------------------------------------- + */ + +abort_test: + sprintf(command, "rm %s\n", test_file); + system(command); + + printf("EFAULT testing complete.\n"); + +} + diff --git a/dmapi/src/suite2/src/test_eventlist.c b/dmapi/src/suite2/src/test_eventlist.c new file mode 100644 index 000000000..56039ae09 --- /dev/null +++ b/dmapi/src/suite2/src/test_eventlist.c @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_set_eventlist(). The +command line is: + + test_eventlist [-v] [-s sid] [-t token] directory + +where: +ls_path + is the path to a specific copy of ls, important only for its size +directory + is the pathname to a DMAPI filesystem. +sid + is the dm_sessid_t value to use. +token + is the dm_token_t value to use (DM_NO_TOKEN is the default). +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +int check_one_event (dm_sessid_t, void*, size_t, dm_token_t, + dm_eventtype_t, int); + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-v] [-s sid] [-t token]" + "ls_path directory \n", Progname); + /* fprintf(stderr, "possible events are:\n"); + for (i = 0; i < ev_namecnt; i++) { + fprintf(stderr, "%s (%d)\n", ev_names[i].name, + ev_names[i].value); + } + */ + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token = DM_NO_TOKEN; + char object[128]; + void *hanp; + size_t hlen; + int Fflag = 0; + int Vflag = 0; + char *name; + int opt; + dm_eventtype_t event; + int error; + void *fshanp; + size_t fshlen; + int i; + char command[128]; + char *ls_path; + char *dir_name; + dm_token_t test_token = DM_NO_TOKEN; + dm_eventset_t eventset; + void *test_vp; + u_int nelemp; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "s:t:uv")) != EOF) { + switch (opt) { + case 's': + sid = atol(optarg); + break; + case 't': + token = atol(optarg); + break; + case 'u': + Vflag=2; + break; + case 'v': + if (Vflag==0) Vflag=1; + break; + case '?': + usage(); + } + } + + if (optind + 2 != argc) + usage(); + ls_path = argv[optind]; + dir_name = argv[optind+1]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't initialize the DMAPI\n"); + exit(1); + } + + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the directory handle */ + if (dm_path_to_handle(dir_name, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for %s\n", dir_name); + exit(1); + } + + /***********************************************\ + |* Test to run on a FILE... *| + \***********************************************/ + + printf("File test beginning...\n"); + sprintf(object, "%s/VeryLongUnlikelyFilename.DMAPIFOO", dir_name); + sprintf(command, "cp %s %s \n", ls_path, object); + system(command); + + if (dm_path_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for %s\n; aborting test", + object); + } + else { + for (i = 0; i < ev_namecnt; i++) { + error = check_one_event(sid, hanp, hlen, token, + ev_names[i].value, Vflag); + switch (ev_names[i].value){ + case DM_EVENT_ATTRIBUTE: case DM_EVENT_DESTROY: + if (error) { + fprintf(stderr, "ERROR: %s failed on a file!\n", + ev_names[i].name); + } + break; + default: + if (!error) { + fprintf(stderr, "ERROR: %s succeeded on a file!\n", + ev_names[i].name); + } + } + } + /*------------------------*\ + |* ## Errno subtests ## *| + \*------------------------*/ + printf("\t(errno subtests beginning...)\n"); + DMEV_ZERO(eventset); + DMEV_SET(DM_EVENT_ATTRIBUTE, eventset); + /*---------------------------------------------------------*/ + EXCLTEST("set", hanp, hlen, test_token, + dm_set_eventlist(sid, hanp, hlen, test_token, + &eventset, DM_EVENT_MAX)) + /*---------------------------------------------------------*/ + if ((test_vp = handle_clone(hanp, hlen)) == NULL) { + fprintf(stderr, + "Cannot create a test handle (%s); skipping EBADF test\n", + ERR_NAME); + } + else { + /* Alter the handle copy to make it (presumably) invalid */ + ((char *) test_vp)[hlen/2]++; + ERRTEST(EBADF, + "set", + dm_set_eventlist(sid, test_vp, hlen, token, + &eventset, DM_EVENT_MAX)) + dm_handle_free(test_vp, hlen); + } + /*---------------------------------------------------------*/ +#ifdef VERITAS_21 + /* Veritas gets a segmentation fault if hanp is NULL or if the + &eventset is out of range. + */ + fprintf(stderr, "\tERROR testing for EFAULT in set (bad hanp): " + "Veritas gets a segmentation fault.\n"); + fprintf(stderr, "\tERROR testing for EFAULT in set (bad eventset): " + "Veritas gets a segmentation fault.\n"); +#else + ERRTEST(EFAULT, + "set", + dm_set_eventlist(sid, NULL, hlen, token, + &eventset, DM_EVENT_MAX)) + ERRTEST(EFAULT, + "set", + dm_set_eventlist(sid, hanp, hlen, token, + (dm_eventset_t*)(-1000), DM_EVENT_MAX)) +#endif + /*---------------------------------------------------------*/ + ERRTEST(EINVAL, + "set (bad session)", + dm_set_eventlist(-100, hanp, hlen, token, + &eventset, DM_EVENT_MAX)) + /*---------------------------------------------------------*/ + ERRTEST(EINVAL, + "set (bad token)", + dm_set_eventlist(sid, hanp, hlen, 0, + &eventset, DM_EVENT_MAX)) + /*---------------------------------------------------------*/ + /* PROBLEM: too-small buffer doesn't produce E2BIG + { + dm_eventset_t *small_evsp = malloc(0); + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, + "can't get filesystem handle from %s; aborting test\n", + dir_name); + } + else { + check_one_event(sid, fshanp, fshlen, token, + DM_EVENT_CREATE, Vflag); + ERRTEST(E2BIG, + "(broken) get", + dm_get_eventlist(sid, fshanp, fshlen, token, + DM_EVENT_MAX, small_evsp, &nelemp)) + check_one_event(sid, fshanp, fshlen, token, + DM_EVENT_INVALID, Vflag); + } + } + /*---------------------------------------------------------*/ + SHAREDTEST("get", hanp, hlen, test_token, + dm_get_eventlist(sid, hanp, hlen, test_token, + DM_EVENT_MAX, &eventset, &nelemp)) + /*---------------------------------------------------------*/ + ERRTEST(EBADF, + "get", + dm_get_eventlist(sid, test_vp, hlen, token, DM_EVENT_MAX, + &eventset, &nelemp)) + /*---------------------------------------------------------*/ +#ifdef VERITAS_21 + /* Veritas gets a segmentation fault if hanp is NULL. */ + + fprintf(stderr, "\tERROR testing for EFAULT in get (bad hanp): " + "Veritas gets a segmentation fault.\n"); +#else + ERRTEST(EFAULT, + "get", + dm_get_eventlist(sid, NULL, hlen, token, DM_EVENT_MAX, + &eventset, &nelemp )) +#endif + /*---------------------------------------------------------*/ + ERRTEST(EINVAL, + "get (bad session)", + dm_get_eventlist(-100, hanp, hlen, token, DM_EVENT_MAX, + &eventset, &nelemp)) + /*---------------------------------------------------------*/ + ERRTEST(EINVAL, + "get (bad token)", + dm_get_eventlist(sid, hanp, hlen, 0, DM_EVENT_MAX, + &eventset, &nelemp)) + /*---------------------------------------------------------*/ + printf("\t(errno subtests complete)\n"); + /*---------------------*\ + |* End of errno tests *| + \*---------------------*/ + + /* Finally, use DM_EVENT_INVALID to delete events... */ + check_one_event(sid, hanp, hlen, token, DM_EVENT_INVALID, Vflag); + } + sprintf(command, "rm %s \n", object); + system(command); + printf("\tFile test complete.\n"); + if (Vflag) printf("\n"); + + /***********************************************\ + |* Test to run on a DIRECTORY... *| + \***********************************************/ + + printf("Directory test beginning...\n"); + sprintf(object, "%s/VeryLongUnlikelyDirectoryName.DMAPIFOO", + dir_name); + sprintf(command, "mkdir %s \n", object); + system(command); + + if (opaque_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for %s\n; aborting test", + object); + } + else { + for (i = 0; i < ev_namecnt; i++) { + error = check_one_event(sid, hanp, hlen, token, + ev_names[i].value, Vflag); + switch (ev_names[i].value){ + case DM_EVENT_CREATE: case DM_EVENT_POSTCREATE: + case DM_EVENT_REMOVE: case DM_EVENT_POSTREMOVE: + case DM_EVENT_RENAME: case DM_EVENT_POSTRENAME: + case DM_EVENT_LINK: case DM_EVENT_POSTLINK: + case DM_EVENT_SYMLINK: case DM_EVENT_POSTSYMLINK: + case DM_EVENT_ATTRIBUTE: case DM_EVENT_DESTROY: + if (error) { + fprintf(stderr, "ERROR: %s failed on a directory!\n", + ev_names[i].name); + } + break; + default: + if (!error) { + fprintf(stderr, "ERROR: %s succeeded on a directory!\n", + ev_names[i].name); + } + } + } + /* Use DM_EVENT_INVALID to delete events... */ + check_one_event(sid, hanp, hlen, token, DM_EVENT_INVALID, Vflag); + } + sprintf(object, "%s/VeryLongUnlikelyDirectoryName.DMAPIFOO", dir_name); + sprintf(command, "rmdir %s\n", object); + system(command); + printf("\tDirectory test complete.\n"); + if (Vflag) printf("\n"); + + /***********************************************\ + |* Test to run on a FILESYSTEM... *| + \***********************************************/ + + printf("Filesystem test beginning...\n"); + + if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) { + fprintf(stderr, + "can't get filesystem handle from %s; aborting test\n", + dir_name); + } + else { + for (i = 0; i < ev_namecnt; i++) { + error = check_one_event(sid, fshanp, fshlen, token, + ev_names[i].value, Vflag); + switch (ev_names[i].value){ + case DM_EVENT_PREUNMOUNT: case DM_EVENT_UNMOUNT: + case DM_EVENT_NOSPACE: case DM_EVENT_DEBUT: + case DM_EVENT_CREATE: case DM_EVENT_POSTCREATE: + case DM_EVENT_REMOVE: case DM_EVENT_POSTREMOVE: + case DM_EVENT_RENAME: case DM_EVENT_POSTRENAME: + case DM_EVENT_LINK: case DM_EVENT_POSTLINK: + case DM_EVENT_SYMLINK: case DM_EVENT_POSTSYMLINK: + case DM_EVENT_ATTRIBUTE: case DM_EVENT_DESTROY: + if (error) { + fprintf(stderr, "ERROR: %s failed on a filesystem!\n", + ev_names[i].name); + } + break; + default: + if (!error) { + fprintf(stderr, "ERROR: %s succeeded on a filesystem!\n", + ev_names[i].name); + } + } + } + /* Use DM_EVENT_INVALID to delete events... */ + check_one_event(sid, fshanp, fshlen, token, DM_EVENT_INVALID, Vflag); + } + printf("\tFilesystem test complete.\n"); + + /***********************************************\ + |* End of tests! *| + \***********************************************/ + + dm_handle_free(fshanp, fshlen); + dm_handle_free(hanp, hlen); + exit(0); +} + +/*------------------------------------------------------------------- + check_one_event: + + Using dm_set_eventlist, set a single event on the object + indicated by the handle. + + Using dm_get_eventlist, check to see that the single event + was set correctly. + -------------------------------------------------------------------*/ + +int +check_one_event ( + dm_sessid_t sid, + void *hanp, + size_t hlen, + dm_token_t token, + dm_eventtype_t event, + int Vflag ) +{ + dm_eventset_t eventset; + dm_eventset_t check_eventset; + u_int nelemp; + int set_count = 0; + int i; + + DMEV_ZERO(eventset); + DMEV_ZERO(check_eventset); + + if (event != DM_EVENT_INVALID) { + DMEV_SET(event, eventset); + } + + if (dm_set_eventlist(sid, hanp, hlen, token, + &eventset, DM_EVENT_MAX)) { + if (Vflag){ + fprintf(stdout, " note: %s could not be set (%s)\n", + ev_value_to_name(event), errno_names[errno]); + } + return (-1); + } + + if (dm_get_eventlist(sid, hanp, hlen, token, + DM_EVENT_MAX, &check_eventset, &nelemp)) { + if (Vflag){ + fprintf(stdout, "dm_get_eventlist failed, %s\n", + errno_names[errno]); + } + return (-2); + } + + /* For each element, see that get_eventlist agrees + * with set_eventlist; if not, make noise. + */ + for (i = 0; i < ev_namecnt; i++) { + int set = DMEV_ISSET(ev_names[i].value, eventset); + int found = DMEV_ISSET(ev_names[i].value, check_eventset); + if (set && !found) { + fprintf(stderr, "ERROR: event %s was set but not found.\n", + ev_names[i].name); + return (-3); + } + else if (!set && found) { + fprintf(stderr, "ERROR: Found unexpected event %s \n", + ev_names[i].name); + return (-4); + } + else if ((Vflag == 2) && !set && !found) { + fprintf(stderr, "clear: %s\n", + ev_names[i].name); + } + else if (Vflag && set && found) { + fprintf(stderr, " SET: %s\n", ev_names[i].name); + set_count++; + } + } + if (Vflag && set_count == 0) { + fprintf(stderr, "\t(All events cleared)\n"); + } + return 0; +} diff --git a/dmapi/src/suite2/src/test_fileattr.c b/dmapi/src/suite2/src/test_fileattr.c new file mode 100644 index 000000000..8ba0fd53e --- /dev/null +++ b/dmapi/src/suite2/src/test_fileattr.c @@ -0,0 +1,713 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- +Automated test of the DMAPI functions: + dm_set_fileattr() + dm_get_fileattr() + dm_get_bulkattr() + dm_get_dirattrs() + +The command line is: + test_fileattr [-s sid] [-n num_files] [-v] ls_path pathname + +where: + sid + is the session ID whose events you you are interested in. + num_files + is the number of test files to create. + ls_path + is the path to a copy of ls, which will be copied as a test file. + pathname + is the filesystem to use for the test. +----------------------------------------------------------------------------*/ + +#define SET_MASK DM_AT_ATIME|DM_AT_MTIME|DM_AT_CTIME|DM_AT_DTIME|\ + DM_AT_UID|DM_AT_GID|DM_AT_MODE|DM_AT_SIZE + +#define GET_MASK DM_AT_EMASK|DM_AT_PMANR|DM_AT_PATTR|\ + DM_AT_DTIME|DM_AT_CFLAG|DM_AT_STAT + +extern int optind; +extern int opterr; +extern char *optarg; + +char *Progname; +int Vflag=0; + + +int +comp_stat ( dm_stat_t expected, + dm_stat_t found, + int i) +{ + int good=0; + if (found.dt_mode != expected.dt_mode) { + fprintf(stderr, + "ERROR: get #%d, expected mode %ld, but found %ld\n", + i, expected.dt_mode, found.dt_mode); + } + else good++; + if (found.dt_uid != expected.dt_uid) { + fprintf(stderr, + "ERROR: get #%d, expected uid %ld, but found %ld\n", + i, expected.dt_uid, found.dt_uid); + } + else good++; + if (found.dt_gid != expected.dt_gid) { + fprintf(stderr, + "ERROR: get #%d, expected gid %ld, but found %ld\n", + i, expected.dt_gid, found.dt_gid); + } + else good++; + if (found.dt_atime != expected.dt_atime) { + fprintf(stderr, + "ERROR: get #%d, expected atime %ld, but found %ld\n", + i, expected.dt_atime, found.dt_atime); + } + else good++; + if (found.dt_mtime != expected.dt_mtime) { + fprintf(stderr, + "ERROR: get #%d, expected mtime %ld, but found %ld\n", + i, expected.dt_mtime, found.dt_mtime); + } + else good++; + if (found.dt_ctime != expected.dt_ctime) { + fprintf(stderr, + "ERROR: get #%d, expected ctime %ld, but found %ld\n", + i, expected.dt_ctime, found.dt_ctime); + } + else good++; + + /* NOTE: dtime gets set to ctime */ + + if (found.dt_dtime != expected.dt_ctime) { + fprintf(stderr, + "ERROR: get #%d, expected dtime %ld, but found %ld\n", + i, expected.dt_ctime, found.dt_dtime); + } + else good++; + if (found.dt_size != expected.dt_size) { + fprintf(stderr, + "ERROR: get #%d, expected size %ld, but found %ld\n", + i, expected.dt_size, found.dt_size); + } + else good++; + if (Vflag){ + if (good==8) { + fprintf(stderr, "report: get #%d had no errors.\n",i); + } else { + fprintf(stderr, "report: %d tests correct for get #%d.\n", + good, i); + } + } + return(good); +} + + +static void +usage(void) +{ + fprintf(stderr, + "Usage: %s [-v] [-s sid] [-n num_files] ls_path pathname\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t test_token = DM_NO_TOKEN; + void *hanp; + size_t hlen; + char *ls_path; + char *pathname; + char test_file[100]; + char command[100]; + int fs_num_files; + int num_files=50; + dm_stat_t *stat_arr; + dm_stat_t dmstat; + dm_fileattr_t fileattr; + char *name; + int opt; + int oops=1; + int i=0; + dm_attrloc_t loc; + size_t buflen = 16*sizeof(dm_stat_t); + size_t rlen; + void *bufp; + dm_stat_t *statbuf; + int loops=0; + int all_file_count=0; + void *fs_hanp; + size_t fs_hlen; + void *targhanp; + size_t targhlen; + char check_name[100]; + char *chk_name_p; + int chk_num; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + opterr = 0; + while ((opt = getopt(argc, argv, "vn:s:")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case 'n': + num_files = atoi(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) { + usage(); + } + ls_path = argv[optind]; + pathname = argv[optind+1]; + + /* Seed the random number generator */ + srand((unsigned int)time(NULL)); + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Dynamically allocate stat_arr; */ + stat_arr = + (dm_stat_t *)malloc(num_files * sizeof(dm_stat_t)); + + printf("Beginning file attribute tests...\n"); + + /* Fill in the dm_stat blocks with lots of junk... + */ + for (i=0; i +#include + +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Test program used to test the DMAPI function dm_punch_hole(). The +command line is: + + test_hole [-v] [-s sid] pathname + +where + ls_path + is the path to a specific copy of ls, important only for its size + pathname + is the path to the test filesystem + sid + is the session ID whose events you you are interested in. + +----------------------------------------------------------------------------*/ + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-v] [-s sid] ls_path directoryname\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *pathname = NULL; + char *ls_path = NULL; + dm_off_t offset = 0; + dm_off_t ex_off = 0; + dm_extent_t extent[20]; + u_int nelem; + dm_size_t length = 0; + void *hanp; + size_t hlen; + dm_token_t test_token; + char *name; + int opt; + int i; + int Vflag = 0; + char filename[128]; + char command[128]; + dm_off_t roff; + dm_size_t rlen; + dm_off_t blocksize = 5; + void *test_vp; + struct stat buf; + struct stat checkbuf; + + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "vs:")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + ls_path = argv[optind]; + pathname = argv[optind+1]; + + if (dm_init_service(&name) == -1) { + fprintf(stdout, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get the directory handle. */ + + if (dm_path_to_handle(pathname, &hanp, &hlen)) { + fprintf(stdout, + "ERROR: can't get handle for directory %s\n", pathname); + exit(1); + } + + printf("Hole test beginning...\n"); + sprintf(filename, "%s/VeryLongUnlikelyFilename.HOLETEST", pathname); + sprintf(command, "cp %s %s \n", ls_path, filename); + system(command); + + if (dm_path_to_handle(filename, &hanp, &hlen)) { + fprintf(stdout, "can't get handle for %s\n; aborting test", + filename); + + sprintf(command, "rm %s \n", filename); + system(command); + fprintf(stdout, "\tHole test aborted.\n"); + + dm_handle_free(hanp, hlen); + exit(1); + } + + /* ## Get the block size using a length-1 probe. ## */ + dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, 1, 0, + &blocksize, &rlen); + + if (blocksize==0) { + fprintf(stdout, "Error: block size appears to be 0!\n"); + + sprintf(command, "rm %s \n", filename); + system(command); + fprintf(stdout, "\tHole test aborted.\n"); + + dm_handle_free(hanp, hlen); + exit(1); + } + + /* Check that dm_probe_hole returns an extent from the next + * highest multiple of the block size, to the end of the file + */ + i = 0; + for (offset = 0; offset < 29604; offset++) { + if (dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length, + &roff, &rlen)) { + fprintf(stdout, "dm_probe_hole failed on pass %lld (%s)\n", + (long long)offset, ERR_NAME); + } + else { + if (rlen != 0) { + fprintf(stdout, + "Error: hole did not extend to end of file!\n"); + } + if (blocksize*(roff/blocksize) != roff) { + fprintf(stdout, + "Error: offset not a multiple of block size!\n"); + } + } + } + + /* Be sure dm_punch_hole doesn't change the time stamp, + * and verify that dm_get_allocinfo shows a hole + * followed by an extent to the end of the file. + */ + for(offset = 28672; offset > 0; offset-=blocksize) { + if (stat(filename, &buf)){ + fprintf(stdout, + "Error: unable to stat the test file; %s (1st)\n", + filename); + continue; + } + if (dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length, + &roff, &rlen)) { + fprintf(stdout, "dm_probe_hole failed, %s\n", + ERR_NAME); + continue; + } + if (roff != offset) { + fprintf(stdout, + "Error: presumed offset was not %lld.\n", + (long long)(roff)); + } + if (dm_punch_hole(sid, hanp, hlen, DM_NO_TOKEN, + roff, length)) { + fprintf(stdout, "dm_punch_hole failed, %s\n", + ERR_NAME); + continue; + } + if (stat(filename, &checkbuf)){ + fprintf(stdout, + "Error: unable to stat the test file. (2nd)\n"); + continue; + } + else { + /* COMPARE BUF AND CHECKBUF! */ +#ifdef linux + if ((buf.st_atime == checkbuf.st_atime) && + (buf.st_mtime == checkbuf.st_mtime) && + (buf.st_ctime == checkbuf.st_ctime)) +#else + if ((buf.st_atim.tv_sec == checkbuf.st_atim.tv_sec) && + (buf.st_atim.tv_nsec == checkbuf.st_atim.tv_nsec) && + (buf.st_mtim.tv_sec == checkbuf.st_mtim.tv_sec) && + (buf.st_mtim.tv_nsec == checkbuf.st_mtim.tv_nsec) && + (buf.st_ctim.tv_sec == checkbuf.st_ctim.tv_sec) && + (buf.st_ctim.tv_nsec == checkbuf.st_ctim.tv_nsec)) +#endif + { + if (Vflag) { + fprintf(stdout, + "\tTime stamp unchanged by hole from offset %lld.\n", + (long long)(offset)); + } + } + else { + fprintf(stdout, + "Error: punch_hole changed file's time stamp.\n"); + } + ex_off=0; + if ((dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, + &ex_off, 1, extent, &nelem) == 1) && + (extent->ex_type == DM_EXTENT_RES) && + (dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, + &ex_off, 1, extent, &nelem) == 0) && + (extent->ex_type == DM_EXTENT_HOLE)) { + if (extent->ex_offset == roff){ + if (Vflag) { + fprintf(stdout, "\tVerified hole at %lld\n", + (long long)(extent->ex_offset)); + } + } + else { + fprintf(stdout, "\tError: get_allocinfo found hole at %lld\n", + (long long)(extent->ex_offset)); + } + } + else { + fprintf(stdout, "\tError: get_allocinfo did not find an " + "extent followed by a hole!\n"); + } + } + } + /*------------------------*\ + |* ## Errno subtests ## *| + \*------------------------*/ + fprintf(stdout, "\t(beginning errno subtests...)\n"); + /*---------------------------------------------------------*/ + ERRTEST(E2BIG, + "probe (from past EOF)", + dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, 30000, length, + &roff, &rlen)) + /*---------------------------------------------------------*/ + /* PROBLEM: No error is produced. + /* off+len >= filesize should produce E2BIG... + ERRTEST(E2BIG, + "probe (to past EOF)", + dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, 15000, 150000, + &roff, &rlen)) + /*---------------------------------------------------------*/ + SHAREDTEST("probe", hanp, hlen, test_token, + dm_probe_hole(sid, hanp, hlen, test_token, + 0, 0, &roff, &rlen)) + /*---------------------------------------------------------*/ + EXCLTEST("punch", hanp, hlen, test_token, + dm_punch_hole(sid, hanp, hlen, test_token, 0, 0)) + /*---------------------------------------------------------*/ + ERRTEST(EAGAIN, + "punch", + dm_punch_hole(sid, hanp, hlen, DM_NO_TOKEN, + 1, length)) + /*---------------------------------------------------------*/ + if ((test_vp = handle_clone(hanp, hlen)) == NULL) { + fprintf(stderr, + "Cannot create a test handle (%s); skipping EBADF test\n", + ERR_NAME); + } + else { + ((char *) test_vp)[hlen/2]++; + ERRTEST(EBADF, + "probe", + dm_probe_hole(sid, test_vp, hlen, DM_NO_TOKEN, + offset, length, + &roff, &rlen)) + ERRTEST(EBADF, + "punch", + dm_punch_hole(sid, test_vp, hlen, DM_NO_TOKEN, + offset, length)) + } + dm_handle_free(test_vp, hlen); + /*---------------------------------------------------------*/ + ERRTEST(EFAULT, + "probe (null handle)", + dm_probe_hole(sid, 0, hlen, DM_NO_TOKEN, offset, length, + &roff, &rlen)) + ERRTEST(EFAULT, + "probe (bad rlen)", + dm_probe_hole(sid, 0, hlen, DM_NO_TOKEN, offset, length, + &roff, (dm_size_t*)(-1000))) + ERRTEST(EFAULT, + "probe (bad roff)", + dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length, + (dm_off_t*)(-1000), &rlen)) + /*---------------------------------------------------------*/ + ERRTEST(EFAULT, + "punch", + dm_punch_hole(sid, 0, hlen, DM_NO_TOKEN, offset, length)) + /*---------------------------------------------------------*/ + ERRTEST(EINVAL, + "probe (bad session)", + dm_probe_hole(-100, hanp, hlen, DM_NO_TOKEN, offset, length, + &roff, &rlen)) + /*---------------------------------------------------------*/ + ERRTEST(EINVAL, + "probe (bad token)", + dm_probe_hole(sid, hanp, hlen, 0, offset, length, + &roff, &rlen)) + /*---------------------------------------------------------*/ + ERRTEST(EINVAL, + "probe (bad token 2)", + dm_probe_hole(sid, hanp, hlen, 0, offset, length, + &roff, &rlen)) + /*---------------------------------------------------------*/ + fprintf(stdout, "\t(errno subtests complete)\n"); + + + sprintf(command, "rm %s \n", filename); + system(command); + printf("Hole test complete.\n"); + + dm_handle_free(hanp, hlen); + exit(0); +} + diff --git a/dmapi/src/suite2/src/test_invis.c b/dmapi/src/suite2/src/test_invis.c new file mode 100644 index 000000000..57d447308 --- /dev/null +++ b/dmapi/src/suite2/src/test_invis.c @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include + +#include + +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Automated test of the DMAPI functions dm_write_invis() and dm_read_invis() + +The command line is: + + test_invis [-s sid] [-v] ls_path pathname + +where: + sid + is the session ID whose events you you are interested in. + ls_path + is the path to a specific copy of ls, important only for its size + pathname + is the filesystem to use for the test. + +DM_WRITE_SYNC is is not supported. +----------------------------------------------------------------------------*/ + +#define OFF_MAX 50 +#define OFF_STEP 5 +#define LEN_MAX 50 +#define LEN_STEP 5 + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-v] [-s sid] ls_path pathname\n", + Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_sessid_t sid = DM_NO_SESSION; + char *dir_name = NULL; + char *ls_path = NULL; + dm_off_t offset = 0; + dm_size_t length = 1; + dm_size_t curlength = 0; + u_char ch; + void *bufp = NULL; + void *hanp; + size_t hlen; + dm_ssize_t rc; + char *name; + char test_file[128]; + char command[128]; + int opt; + int i; + int j; + int k; + int Vflag=0; + struct stat statbuf; + struct stat checkbuf; + dm_token_t test_token; + void* test_vp; + int cont; + int error_reported; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "vs:")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) + usage(); + ls_path = argv[optind]; + dir_name = argv[optind+1]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /* Get a random character for read/write tests */ + srand((unsigned int)time(NULL)); + ch = (char)rand(); + + printf("Invisible read/write tests beginning...\n"); + + /* File creation loop*/ + for(i=0; i (b) ? (a) : (b)) + length = max((dm_size_t)(i), length); + offset = (dm_off_t)(j); + + sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d", + dir_name, i, j); + + if (stat(test_file, &statbuf)){ + fprintf(stdout, + "Error: unable to stat test file; %s (before test)\n", + test_file); + continue; + } + + if (dm_path_to_handle(test_file, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for %s; bypassing test\n", + test_file); + continue; + } + +printf("test_invis/%d: checking length(%d)>0\n", __LINE__, length); + if (length > curlength) { +printf("test_invis/%d: bufp malloc(%d)\n", __LINE__, length); + if(curlength>0) + free(bufp); + if ((bufp = malloc(length)) == NULL) { + fprintf(stderr, "malloc of %d bytes failed\n", length); + continue; + } + curlength = length; + memset(bufp, ch, length); + } + + rc = dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, + 0, offset, length, bufp); + cont = 0; + if (rc < 0) { + fprintf(stderr, "dm_write_invis failed, %s\n", ERR_NAME); + cont=1; + } else if (rc != length) { + fprintf(stderr, "expected to write %lld bytes, actually " + "wrote %lld\n", length, rc); + cont=1; + } + if(cont) + continue; + + /* Timestamp checking, part 1 */ + if (stat(test_file, &checkbuf)){ + fprintf(stdout, + "Error: unable to stat the test file; %s (after write)\n", + test_file); + } + else { +#if 0 + if ((statbuf.st_atim.tv_sec == checkbuf.st_atim.tv_sec) && + (statbuf.st_atim.tv_nsec == checkbuf.st_atim.tv_nsec) && + (statbuf.st_mtim.tv_sec == checkbuf.st_mtim.tv_sec) && + (statbuf.st_mtim.tv_nsec == checkbuf.st_mtim.tv_nsec) && + (statbuf.st_ctim.tv_sec == checkbuf.st_ctim.tv_sec) && + (statbuf.st_ctim.tv_nsec == checkbuf.st_ctim.tv_nsec)) +#else + if ((statbuf.st_atime == checkbuf.st_atime) && + (statbuf.st_mtime == checkbuf.st_mtime) && + (statbuf.st_ctime == checkbuf.st_ctime)) +#endif + { + if (Vflag) { + printf("Report: time stamp unchanged by write\n"); + } + } + else { + printf("Error: time stamp changed by write\n"); + } + } + + rc = dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN, + offset, length, bufp); + if (rc < 0) { + fprintf(stderr, "dm_read_invis failed, %s\n", ERR_NAME); + continue; + } + else if (rc != length) { + fprintf(stderr, "expected to read %lld bytes, actually " + "wrote %lld\n", length, rc); + continue; + } + else { + /* Be sure the buffer is filled with the test char */ + error_reported = 0; +printf("%s/%d: i=%d\n", __FILE__, __LINE__, i); + for (k=0; k + +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- + +Automated test of the DMAPI functions dm_set_region() and dm_get_region(). + +The command line is: + + test_region [-s sid] ls_path directory + +where + pathname + is the name of a file + ls_path + is the path to a specific copy of ls, important only for its size + sid + is the session ID whose events you you are interested in. +----------------------------------------------------------------------------*/ + +#define NELEM 1 + +#ifndef linux +extern char *sys_errlist[]; +#endif +extern int optind; +extern char *optarg; + + +char *Progname; + +static struct { + char *name; + int value; +} rg_events[3] = { + { "DM_REGION_READ", DM_REGION_READ }, + { "DM_REGION_WRITE", DM_REGION_WRITE }, + { "DM_REGION_TRUNCATE", DM_REGION_TRUNCATE } +}; + +u_int reg_flags[8] = {DM_REGION_NOEVENT, + DM_REGION_READ, + DM_REGION_WRITE, + DM_REGION_TRUNCATE, + DM_REGION_READ | DM_REGION_WRITE, + DM_REGION_READ | DM_REGION_TRUNCATE, + DM_REGION_WRITE | DM_REGION_TRUNCATE, + DM_REGION_READ | DM_REGION_WRITE | DM_REGION_TRUNCATE}; + + +static int nevents = sizeof(rg_events)/sizeof(rg_events[0]); + + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage:\t%s [-s sid] ls_path pathname\n", Progname); + exit(1); +} + + +int +main( + int argc, + char **argv) +{ + dm_region_t region = { 0, 0, 0 }; + dm_region_t checkregion = { 0, 0, 0 }; + dm_sessid_t sid = DM_NO_SESSION; + char *dir_name = NULL; + char *ls_path = NULL; + char object[128]; + char command[128]; + u_int exactflag; + u_int nelem_read = 0; + void *hanp; + size_t hlen; + char *name; + int opt; + int i; + int Vflag = 0; + dm_token_t test_token = DM_NO_TOKEN; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + /* Crack and validate the command line options. */ + + while ((opt = getopt(argc, argv, "vo:l:s:")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case 'o': + region.rg_offset = atol(optarg); + break; + case 'l': + region.rg_size = atol(optarg); + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 > argc) + usage(); + ls_path = argv[optind]; + dir_name = argv[optind+1]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + /***********************************************\ + |* Beginning the testing of set/get_region... *| + \***********************************************/ + + printf("Region test beginning...\n"); + sprintf(object, "%s/VeryLongUnlikelyFilename.REGIONTEST", dir_name); + sprintf(command, "cp %s %s \n", ls_path, object); + system(command); + + /* Get the test file's handle. */ + if (dm_path_to_handle(object, &hanp, &hlen)) { + fprintf(stderr, "can't get handle for file %s\n", object); + exit(1); + } + /* Loop over all possible region flag combinations, + * setting and getting. See what works! + */ + for (i = 0; i < 8; i++) { + region.rg_flags = reg_flags[i]; + if (dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, NELEM, + ®ion, &exactflag)) { + fprintf(stderr, "dm_set_region failed, %s\n", + ERR_NAME); + continue; + } + if (exactflag != DM_TRUE){ + fprintf(stdout, "oops...exactflag was false!\n"); + } + if (dm_get_region(sid, hanp, hlen, DM_NO_TOKEN, NELEM, + &checkregion, &nelem_read)) { + fprintf(stderr, "dm_get_region failed, %s\n", + ERR_NAME); + continue; + } + if (region.rg_flags != checkregion.rg_flags) { + fprintf(stdout, "set region flags %d, but found %d\n", + region.rg_flags, checkregion.rg_flags); + } + else if (Vflag) { + fprintf(stdout, "Test #%d okay\n", i); + } + } + + /*************************************\ + |* Correct-input testing complete. *| + |* Beginning improper-input testing. *| + \*************************************/ + printf("\t(errno subtests beginning...)\n"); + region.rg_flags = 7; + + /**** SET tests ****/ + /*---------------------------------------------------------*/ + ERRTEST(E2BIG, + "set", + dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, + 2, ®ion, &exactflag)) + ERRTEST(E2BIG, + "set", + dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, + -1, ®ion, &exactflag)) + /*---------------------------------------------------------*/ + EXCLTEST("set", hanp, hlen, test_token, + dm_set_region(sid, hanp, hlen, test_token, + NELEM, ®ion, &exactflag)) + /*---------------------------------------------------------*/ + ERRTEST(EFAULT, + "set", + dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, + NELEM, (dm_region_t*)(-1000), &exactflag)) + ERRTEST(EFAULT, + "set", + dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, + NELEM, ®ion, (dm_boolean_t*)(-1000))) + /*---------------------------------------------------------*/ + ERRTEST(EINVAL, + "set (bad session id)", + dm_set_region(-100, hanp, hlen, DM_NO_TOKEN, + NELEM, ®ion, &exactflag)) + /*---------------------------------------------------------*/ + + /**** GET tests ****/ + /*---------------------------------------------------------*/ + ERRTEST (E2BIG, + "get", + dm_get_region(sid, hanp, hlen, DM_NO_TOKEN, + 0, &checkregion, &nelem_read)) + /*---------------------------------------------------------*/ + ERRTEST(EFAULT, + "get (bad handle)", + dm_get_region(sid, NULL, hlen, DM_NO_TOKEN, + NELEM, &checkregion, &nelem_read)) + /*---------------------------------------------------------*/ + ERRTEST(EFAULT, + "get (bad regbufp)", + dm_get_region(sid, hanp, hlen, DM_NO_TOKEN, + NELEM, (dm_region_t *)(-1000), &nelem_read)) + /*---------------------------------------------------------*/ + ERRTEST(EFAULT, + "get (bad nelemp)", + dm_get_region(sid, hanp, hlen, DM_NO_TOKEN, + NELEM, &checkregion, (u_int *)(-1000))) + /*---------------------------------------------------------*/ + SHAREDTEST("get", hanp, hlen, test_token, + dm_get_region(sid, hanp, hlen, test_token, + NELEM, &checkregion, &nelem_read)) + /*---------------------------------------------------------*/ + ERRTEST(EINVAL, + "get", + dm_get_region(-100, hanp, hlen, DM_NO_TOKEN, + NELEM, &checkregion, &nelem_read)) + /*---------------------------------------------------------*/ + printf("\t(errno subtests complete)\n"); + /**********************************\ + |* End of improper-input testing. *| + \**********************************/ + + sprintf(command, "rm %s \n", object); + system(command); + printf("Region test complete.\n"); + + /***********************************\ + |* End of set/get_region testing. *| + \***********************************/ + + dm_handle_free(hanp, hlen); + exit(0); +} diff --git a/dmapi/src/suite2/src/test_rights.c b/dmapi/src/suite2/src/test_rights.c new file mode 100644 index 000000000..53be8698e --- /dev/null +++ b/dmapi/src/suite2/src/test_rights.c @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef linux +#include +#endif + +/*--------------------------------------------------------------------------- +Automated test of access rights, involving many DMAPI functions + +The command line is: + test_rights [-s sid] [-v] ls_path pathname + +where: + sid + is the session ID whose events you you are interested in. + ls_path + is the path to a copy of ls, which will be copied as a test file. + pathname + is the filesystem to use for the test. +----------------------------------------------------------------------------*/ + +#define NUM_TOKENS 4 + +extern int optind; +extern int opterr; +extern char *optarg; + +char *Progname; +int Vflag=0; + +static void +usage(void) +{ + fprintf(stderr, + "Usage: %s [-v] [-s sid] ls_path pathname\n", + Progname); + exit(1); +} + + +int +main(int argc, char **argv) { + + dm_sessid_t sid = DM_NO_SESSION; + dm_token_t token[NUM_TOKENS]; + dm_token_t test_token; + void *fs_hanp; + size_t fs_hlen; + void *dir_hanp; + size_t dir_hlen; + void *ap; + size_t alen; + void *bp; + size_t blen; + void *cp; + size_t clen; + char *name; + char *ls_path; + char *pathname; + char fname_a[100]; + char fname_b[100]; + char fname_c[100]; + char command[150]; + int opt; + int i=0; + int error_count=0; + + if (Progname = strrchr(argv[0], '/')) { + Progname++; + } else { + Progname = argv[0]; + } + + opterr = 0; + while ((opt = getopt(argc, argv, "vn:s:")) != EOF) { + switch (opt) { + case 'v': + Vflag++; + break; + case 's': + sid = atol(optarg); + break; + case '?': + usage(); + } + } + if (optind + 2 != argc) { + usage(); + } + ls_path = argv[optind]; + pathname = argv[optind+1]; + + if (dm_init_service(&name) == -1) { + fprintf(stderr, "Can't inititalize the DMAPI\n"); + exit(1); + } + if (sid == DM_NO_SESSION) + find_test_session(&sid); + + printf("Beginning access rights testing...\n"); + + sprintf(fname_a, "%s/DMAPI_rights_test_file_a", pathname); + sprintf(command, "cp %s %s\n", ls_path, fname_a); + system(command); + + if (dm_path_to_handle(fname_a, &ap, &alen)) { + fprintf(stderr, "ERROR: can't get handle for %s; %s\n", + fname_a, ERR_NAME); + goto abort_test; + } + + sprintf(fname_b, "%s/DMAPI_rights_test_file_b", pathname); + sprintf(command, "cp %s %s\n", ls_path, fname_b); + system(command); + + if (dm_path_to_handle(fname_b, &bp, &blen)) { + fprintf(stderr, "ERROR: can't get handle for %s; %s\n", + fname_b, ERR_NAME); + goto abort_test; + } + + sprintf(fname_c, "%s/DMAPI_rights_test_file_c", pathname); + sprintf(command, "cp %s %s\n", ls_path, fname_c); + system(command); + + if (dm_path_to_handle(fname_c, &cp, &clen)) { + fprintf(stderr, "ERROR: can't get handle for %s; %s\n", + fname_c, ERR_NAME); + goto abort_test; + } + + if (dm_path_to_fshandle(pathname, &fs_hanp, &fs_hlen)) { + fprintf(stderr, "ERROR: can't get handle for %s; %s\n", + pathname, ERR_NAME); + goto abort_test; + } + + sprintf(pathname, "%s/DMAPI_rights_test_dir", pathname); + sprintf(command, "mkdir %s\n", pathname); + system(command); + + if (dm_path_to_handle(pathname, &dir_hanp, &dir_hlen)) { + fprintf(stderr, "ERROR: can't get handle for %s; %s\n", + pathname, ERR_NAME); + goto abort_test; + } + + /* Test remaining functions for appropriate + * right requirements... + *------------------------------------------------------------*/ + { + dm_off_t off = (dm_off_t)0; + dm_extent_t extent; + u_int nelem_ret; + SHAREDTEST("get_allocinfo", ap, alen, test_token, + dm_get_allocinfo(sid, ap, alen, test_token, + &off, 1, &extent, &nelem_ret)) + } + /*------------------------------------------------------------*/ + { + void *bufp=(void*)malloc(5*sizeof(dm_attrlist_t)); + size_t rlen; + SHAREDTEST("getall_dmattr", ap, alen, test_token, + dm_getall_dmattr(sid, ap, alen, test_token, + 5, bufp, &rlen)) + } + /*------------------------------------------------------------*/ + { + dm_attrloc_t loc; + SHAREDTEST("init_attrloc", dir_hanp, dir_hlen, test_token, + dm_init_attrloc(sid, dir_hanp, dir_hlen, test_token, + &loc)) + } + /*------------------------------------------------------------*/ + /* mkdir_by_handle is NOT SUPPORTED in current SGI DMAPI + { + SHAREDTEST("mkdir_by_handle", fs_hanp, fs_hlen, test_token, + dm_mkdir_by_handle(sid, fs_hanp, fs_hlen, test_token, + dir_hanp, dir_hlen, "FUBAR_DIR")) + } + /*------------------------------------------------------------*/ + { dm_eventset_t eventset; + DMEV_ZERO(eventset); + EXCLTEST("set_disp", fs_hanp, fs_hlen, test_token, + dm_set_disp(sid, fs_hanp, fs_hlen, test_token, + &eventset, DM_EVENT_MAX)) + } + /*------------------------------------------------------------*/ + { dm_attrname_t attrname={"TEST"}; + EXCLTEST("set_return...", fs_hanp, fs_hlen, test_token, + dm_set_return_on_destroy(sid, fs_hanp, fs_hlen, test_token, + &attrname, DM_TRUE)) + } + /*------------------------------------------------------------*/ + + /* Create the tokens */ + for (i=1; i