File: [Development] / xfs-cmds / xfstests / dmapi / src / suite2 / src / test_bulkall.c (download)
Revision 1.2, Mon May 31 18:19:44 2004 UTC (13 years, 4 months ago) by roehrich
Branch: MAIN
CVS Tags: HEAD Changes since 1.1: +4 -3
lines
Make the dm_bulkall test output match that of the dm_bulkattr test
Change output to match test_bulkattr.c
|
/*
* 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.
*
* October 1, 2003: Dean Roehrich
* - Adapted to test dm_get_bulkall, from migfind.c.
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <lib/hsm.h>
#include <getopt.h>
extern char *optarg;
extern int optind, optopt, opterr;
char *Progname;
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_attrname_t*, size_t,
int, int);
void usage(char *);
void
usage(
char *prog)
{
fprintf(stderr, "Usage: %s ", prog);
fprintf(stderr, " <-a attrname> [-b bufsz] [-v] [-q]");
fprintf(stderr, " filesystem\n");
}
#define V_PRINT 0x01
#define V_VERBOSE 0x02
int
main(
int argc,
char *argv[])
{
int c;
int error;
char *fsname;
dm_sessid_t sid;
void *fs_hanp;
size_t fs_hlen;
dm_attrname_t dmattr;
size_t bufsz = 65536;
dm_size_t ret;
int extras = 0;
int verbose = V_PRINT;
Progname = argv[0];
memset(&dmattr, 0, sizeof(dmattr));
while ((c = getopt(argc, argv, "a:b:evq")) != EOF) {
switch (c) {
case 'a':
if (strlen(optarg) > (DM_ATTR_NAME_SIZE-1)){
printf("Arg for -a too long\n");
exit(1);
}
strcpy((char*)dmattr.an_chars, optarg);
break;
case 'b':
bufsz = atoi(optarg);
break;
case 'e':
extras++;
break;
case 'v':
verbose |= V_VERBOSE;
break;
case 'q':
verbose &= ~V_PRINT;
break;
case '?':
default:
usage(Progname);
exit(1);
}
}
if (optind >= argc) {
usage(Progname);
exit(1);
}
if (dmattr.an_chars[0] == '\0') {
usage(Progname);
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);
}
if( dm_get_config(fs_hanp, fs_hlen, DM_CONFIG_BULKALL, &ret) ||
(ret != DM_TRUE)) {
printf("Kernel does not have dm_get_bulkall\n");
exit(1);
}
/*
* Get the attributes of all files in the filesystem
*/
error = scan_fs(sid, fs_hanp, fs_hlen, &dmattr, bufsz, extras, verbose);
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);
}
void
my_print_victim(
void *hanp,
size_t hlen,
dm_xstat_t *xbuf,
dm_stat_t *sbuf,
int extras,
int verbose)
{
u_int attrlen;
char *attrval;
if (hlen > HANDLE_LEN) {
if (verbose & V_PRINT)
printf("-- invalid length --\n");
}
else {
char handle_str[HANDLE_STR];
if (verbose & V_PRINT) {
printf("%d\t", hlen);
hantoa(hanp, hlen, handle_str);
printf("%s ", handle_str);
if (extras) {
printf("size=%lld ",
(int64_t)sbuf->dt_size);
printf("ino=%lld ",
(int64_t)sbuf->dt_ino);
}
}
attrval = DM_GET_VALUE(xbuf,
dx_attrdata, char*);
attrlen = DM_GET_LEN(xbuf,
dx_attrdata);
/* Hmmm, a hole in the dmapi spec.
* No way to have a null pointer
* for the value. No way to
* distinguish between a zero-length
* attribute value and not finding
* the attribute in the first place.
*
* Punt. Since I cannot get a null
* pointer for the value, let's look
* at the length. If it's zero,
* we'll say the attribute was
* not found.
*/
if (verbose & V_PRINT) {
if (attrlen) {
if (isalpha(attrval[0]) )
printf("(%s)\n", attrval);
else
printf("<len=%d>\n", attrlen);
}
else {
printf("<none>\n");
}
}
}
}
/*
* Get the attributes for all the files in a filesystem in bulk,
* including the specified dmattr,
* and print out the handles and dmattr values.
*/
int
scan_fs(
dm_sessid_t sid,
void *fs_hanp,
size_t fs_hlen,
dm_attrname_t *dmattr,
size_t buflen,
int extras,
int verbose)
{
u_int mask; /* attributes to scan for */
dm_xstat_t *dm_xstatbuf, *xbuf; /* attributes buffer */
dm_stat_t *sbuf;
dm_attrloc_t locp; /* opaque location in fs */
size_t rlenp; /* ret length of stat info */
void *hanp; /* file handle */
size_t hlen; /* file handle */
int more; /* loop terminator */
int error;
#ifdef VERITAS_21
if (buflen > 65536)
buflen= 65536;
#endif
dm_xstatbuf = (dm_xstat_t *)calloc(1, buflen);
if (dm_xstatbuf == 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_xstatbuf);
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_bulkall(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
mask, dmattr, &locp, buflen,
dm_xstatbuf, &rlenp);
if (verbose & V_VERBOSE)
fprintf(stderr, "BULKALL more=%d, rlen=%d\n", more, rlenp);
if (more == -1) {
errno_msg("%s/%d: Can't get bulkall 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_xstat_t structure in the returned buffer.
*/
xbuf = dm_xstatbuf;
while (xbuf != NULL) {
sbuf = &xbuf->dx_statinfo;
if (S_ISREG(sbuf->dt_mode)) {
hanp = DM_GET_VALUE(sbuf, dt_handle, void *);
hlen = DM_GET_LEN(sbuf, dt_handle);
my_print_victim(hanp, hlen, xbuf, sbuf,
extras, verbose);
}
/* The sbuf has the offset to the next xbuf */
xbuf = DM_STEP_TO_NEXT(sbuf, dm_xstat_t *);
}
} while (more == 1);
free(dm_xstatbuf);
if (more == -1)
return(1);
return(0);
}