cmd/xfsprogs/libdm/dmapi_tests/README 1.1 Renamed to cmd/xfstests/dmapi/README

This commit is contained in:
Nathan Scott
2001-01-17 01:24:14 +00:00
parent 3c6a65bfdd
commit 785bb63731
113 changed files with 27063 additions and 0 deletions
+38
View File
@@ -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.
+166
View File
@@ -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 <ctype.h>
#include <lib/hsm.h>
#ifdef linux
#include <string.h>
#include <malloc.h>
#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);
}
+174
View File
@@ -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 <lib/hsm.h>
#ifdef linux
#include <string.h>
#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, &region,
&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);
}
@@ -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 <lib/hsm.h>
#ifdef linux
#include <string.h>
#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);
}
+164
View File
@@ -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 <lib/hsm.h>
#ifdef linux
#include <string.h>
#include <malloc.h>
#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);
}
File diff suppressed because it is too large Load Diff
+212
View File
@@ -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 <lib/hsm.h>
/*******************************************************************************
*
* 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);
}
}
}
+166
View File
@@ -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 <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <lib/dmport.h>
#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 */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+62
View File
@@ -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.
+286
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <lib/hsm.h>
#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);
}
+488
View File
@@ -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 <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <lib/hsm.h>
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<lim.rlim_cur; i++)
(void)close(i);
/*
* For error reporting, we re-direct stdout and stderr to a
* logfile.
*/
if ((fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC, 0755)) < 0) {
errno_msg("Can't open logfile %s", logfile);
return(1);
}
(void)dup2(fd, STDOUT_FILENO);
(void)dup2(fd, STDERR_FILENO);
close(fd);
/*
* Set up signals so that we can wait for spawned children
*/
act.sa_handler = migin_exit;
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);
}
void
migin_exit(void)
{
dm_sessid_t *sidbuf, *sid;
void *infobuf;
char *cp;
u_int nsessions, nret;
int i, found, error;
size_t buflen, retlen;
sidbuf = NULL;
infobuf = NULL;
/*
* We could try and kill off all our kids, but we're not
* 'Mr. Mean', so we just wait for them to die.
*/
err_msg("%s: waiting for all children to die...", Progname);
while (wait3((int *)0, WNOHANG, (struct rusage *)0) > 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<nret; i++) {
error = dm_query_session(*sid, buflen, infobuf, &retlen);
if (error == -1)
continue; /* We just punt on errors */
if (strstr(infobuf, cp)) {
found = 1;
break;
}
sid++;
}
/*
* XXXX FIXME XXX
*
* Should do a set_disp to 0 and then drain the session
* queue as well. On the SGI, we'll need to make the
* filesystem handle global so that we can get at it
*/
if (!found) {
err_msg("Can't find session to shut down");
goto out;
}
error = dm_destroy_session(*sid);
if (error == -1) {
errno_msg("Can't shut down session");
}
out:
if (infobuf)
free(infobuf);
if (sidbuf)
free(sidbuf);
exit(0);
}
File diff suppressed because it is too large Load Diff
+331
View File
@@ -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 <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <fcntl.h>
#include <lib/hsm.h>
#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 <options> 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<ret; i++) {
printf("\tRegion %d:\n", i);
#ifdef __sgi
printf("\t\toffset %lld, ", rgn[i].rg_offset);
printf("size %lld, ", rgn[i].rg_size);
#else
printf("\t\toffset %ld, ", rgn[i].rg_offset);
printf("size %ld, ", rgn[i].rg_size);
#endif
printf("flags 0x%x", rgn[i].rg_flags);
printf(" ( ");
if (rgn[i].rg_flags & DM_REGION_NOEVENT)
printf("noevent ");
if (rgn[i].rg_flags & DM_REGION_READ)
printf("read ");
if (rgn[i].rg_flags & DM_REGION_WRITE)
printf("write ");
if (rgn[i].rg_flags & DM_REGION_TRUNCATE)
printf("trunc ");
printf(" )\n");
}
return(0);
}
/*
* Get the complete list of events for a file.
*/
int
event_info(
dm_sessid_t sid,
void *hanp,
size_t hlen)
{
u_int i;
u_int ret;
dm_eventset_t eventlist;
DMEV_ZERO(eventlist);
if (dm_get_eventlist(sid, hanp, hlen, DM_NO_TOKEN, DM_EVENT_MAX,
&eventlist, &ret)) {
errno_msg("Can't get list of events");
return(1);
}
printf("\n\tEvent list: \n\t\t");
if (DMEV_ISSET(DM_EVENT_MOUNT, eventlist))
printf("mount ");
if (DMEV_ISSET(DM_EVENT_PREUNMOUNT, eventlist))
printf("preunmount ");
if (DMEV_ISSET(DM_EVENT_UNMOUNT, eventlist))
printf("unmount ");
if (DMEV_ISSET(DM_EVENT_DEBUT, eventlist))
printf("debut ");
if (DMEV_ISSET(DM_EVENT_CREATE, eventlist))
printf("create ");
if (DMEV_ISSET(DM_EVENT_POSTCREATE, eventlist))
printf("postcreate ");
if (DMEV_ISSET(DM_EVENT_REMOVE, eventlist))
printf("remove ");
if (DMEV_ISSET(DM_EVENT_POSTREMOVE, eventlist))
printf("postmount ");
if (DMEV_ISSET(DM_EVENT_RENAME, eventlist))
printf("rename ");
if (DMEV_ISSET(DM_EVENT_POSTRENAME, eventlist))
printf("postrename ");
if (DMEV_ISSET(DM_EVENT_LINK, eventlist))
printf("link ");
if (DMEV_ISSET(DM_EVENT_POSTLINK, eventlist))
printf("postlink ");
if (DMEV_ISSET(DM_EVENT_SYMLINK, eventlist))
printf("symlink ");
if (DMEV_ISSET(DM_EVENT_POSTSYMLINK, eventlist))
printf("postsymlink ");
if (DMEV_ISSET(DM_EVENT_READ, eventlist))
printf("read ");
if (DMEV_ISSET(DM_EVENT_WRITE, eventlist))
printf("write ");
if (DMEV_ISSET(DM_EVENT_TRUNCATE, eventlist))
printf("truncate ");
if (DMEV_ISSET(DM_EVENT_ATTRIBUTE, eventlist))
printf("attribute ");
if (DMEV_ISSET(DM_EVENT_DESTROY, eventlist))
printf("destroy ");
if (DMEV_ISSET(DM_EVENT_NOSPACE, eventlist))
printf("nospace ");
if (DMEV_ISSET(DM_EVENT_USER, eventlist))
printf("user ");
printf("\n");
return(0);
}
/*
* Print out the handle for a file
*/
int
handle_info(
dm_sessid_t sid,
void *hanp,
size_t hlen)
{
printf("\n\tHandle (handle length, value) \n\t\t");
print_handle(hanp, hlen);
return(0);
}
/*
* Get the allocation info for a file. We pick some small number
* of extents to get the residency info on at one time
*/
int
alloc_info(
dm_sessid_t sid,
void *hanp,
size_t hlen)
{
int i, more;
dm_off_t offset;
u_int nextents, nret;
dm_extent_t ext[NUM_EXTENTS];
nextents = NUM_EXTENTS;
offset = 0;
printf("\n\tAllocation info \n");
do {
more = dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, &offset,
nextents, ext, &nret);
if (more == -1) {
errno_msg("Can't get alloc info for file");
return(1);
}
for (i=0; i<nret; i++) {
printf("\t\tExtent %d ", i);
if (ext[i].ex_type == DM_EXTENT_RES)
printf("(resident): ");
if (ext[i].ex_type == DM_EXTENT_HOLE)
printf("(hole): ");
#ifdef __sgi
printf("offset %lld, ", ext[i].ex_offset);
printf("len %lld\n", ext[i].ex_length);
#else
printf("offset %ld, ", ext[i].ex_offset);
printf("len %ld\n", ext[i].ex_length);
#endif
}
} while (more == 1);
return(0);
}
+322
View File
@@ -0,0 +1,322 @@
/*
* Simple Mr. Mean that can manipulate and torch sessions
*
* 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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <lib/dmport.h>
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 <options>\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 <specific_sid>\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<nsids; i++, sidp++) {
if (sid_flag) {
/*
* If we're only looking for one sid, then
* we can skip this one if there's no match
*/
if (onesid != *sidp)
continue;
}
if (list_flag)
print_session(*sidp);
if (token_flag)
print_tokens(*sidp);
if (kill_flag)
kill_session(*sidp);
}
return(0);
}
/*
* Print out info about a sessions
*/
void
print_session(dm_sessid_t sid)
{
char buf[DM_SESSION_INFO_LEN];
size_t ret;
if (dm_query_session(sid,DM_SESSION_INFO_LEN,(void *)buf, &ret) == -1) {
errno_msg("Can't get session info");
return;
}
printf("Session (%d) name: %s\n", sid, buf);
return;
}
/*
* Get all the tokens for a session
*/
void
print_tokens(dm_sessid_t sid)
{
dm_token_t *tbuf;
int error;
u_int i, ntokens;
error = get_tokens(sid, &tbuf, &ntokens);
if (error)
return;
printf("\tTokens (%d): ", ntokens);
for (i=0; i<ntokens; i++)
printf("%d ", *tbuf++);
printf("\n");
free(tbuf);
return;
}
/*
* Try and kill a session
*/
void
kill_session(dm_sessid_t sid)
{
dm_token_t *tbuf;
int error;
u_int i, ntokens;
/*
* Get all the tokens in the system so we can respond to them
*/
error = get_tokens(sid, &tbuf, &ntokens);
if (error)
return;
if (ntokens && Verbose)
printf("\tResponding to events for sid %d, tokens: \n", sid);
for (i=0; i<ntokens; i++) {
if (Verbose)
printf("\t\t%d ", *tbuf);
if (dm_respond_event(sid, *tbuf, DM_RESP_ABORT, EIO, 0, NULL) == -1)
errno_msg("Can't respond to event, sid %d token %d",
sid, *tbuf);
tbuf++;
}
if (Verbose)
printf("\tDestroying session %d\n", sid);
if (dm_destroy_session(sid) == -1)
errno_msg("Can't shut down session %d", sid);
return;
}
int
get_sessions(
dm_sessid_t **sidpp,
u_int *nsidp)
{
dm_sessid_t *sidbuf;
int more, error;
u_int nsids, nret;
/*
* Pick an arbitrary number of sessions to get info for.
* If it's not enough, then we can always resize our buffer
*/
error = 0;
nsids = 32;
sidbuf = malloc(nsids * sizeof(dm_sessid_t));
if (sidbuf == NULL) {
err_msg("Can't malloc memory");
error = 1;
goto out;
}
if (dm_getall_sessions(nsids, sidbuf, &nret) == -1) {
if (errno != E2BIG) {
errno_msg("Can't get list of sessions");
error = 1;
goto out;
}
free(sidbuf);
nsids = nret;
sidbuf = malloc(nsids * sizeof(dm_sessid_t));
if (sidbuf == NULL) {
err_msg("Can't malloc memory");
error = 1;
goto out;
}
if (dm_getall_sessions(nsids, sidbuf, &nret) == -1) {
if (error == -1) {
errno_msg("Can't get sessions with new buf");
error = 1;
goto out;
}
}
}
out:
if (error && (sidbuf != NULL) )
free(sidbuf);
else {
*sidpp = sidbuf;
*nsidp = nret;
}
return(error);
}
/*
* Get all tokens in the session
*/
int
get_tokens(
dm_sessid_t sid,
dm_token_t **bufpp,
u_int *nretp)
{
dm_token_t *tbuf;
u_int ntokens, nret;
int error;
error = 0;
ntokens = 1024;
tbuf = (dm_token_t *)malloc(ntokens * sizeof(dm_token_t));
if (tbuf == NULL)
goto out;
if (dm_getall_tokens(sid, ntokens, tbuf, &nret) == -1) {
if (errno != E2BIG) {
errno_msg("Can't get all tokens");
goto out;
}
free(tbuf);
ntokens = nret;
tbuf = (dm_token_t *)malloc(ntokens * sizeof(dm_token_t));
if (tbuf == NULL)
goto out;
if (dm_getall_tokens(sid, ntokens, tbuf, &nret) == -1) {
errno_msg("Can't get all tokens");
goto out;
}
}
out:
if (error && (tbuf != NULL))
free(tbuf);
else {
*bufpp = tbuf;
*nretp = nret;
}
return(error);
}
File diff suppressed because it is too large Load Diff
+70
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <linux/dmapi_kern.h>
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 );
}
+67
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <linux/dmapi_kern.h>
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 );
}

Some files were not shown because too many files have changed in this diff Show More