mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
cmd/xfsprogs/libdm/dmapi_tests/README 1.1 Renamed to cmd/xfstests/dmapi/README
This commit is contained in:
@@ -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.
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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, ®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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
@@ -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.
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
@@ -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);
|
||||||
|
}
|
||||||
@@ -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
@@ -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 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
Reference in New Issue
Block a user