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