[BACK]Return to test_bulkattr.c CVS log [TXT][DIR] Up to [Development] / xfs-cmds / xfstests / dmapi / src / suite2 / src

File: [Development] / xfs-cmds / xfstests / dmapi / src / suite2 / src / test_bulkattr.c (download)

Revision 1.1, Tue Oct 7 18:26:55 2003 UTC (14 years ago) by roehrich
Branch: MAIN
CVS Tags: HEAD

Add DMAPI tests for dm_get_bulkall and dm_get_bulkattr
Test for dm_get_bulkattr.

/*
 * 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 2, 2003: Dean Roehrich
 *  - Adapted to test dm_get_bulkattr + dm_get_dmattr, 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	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_attrname_t*,
			size_t, int);
void		usage(char *);

void
usage(
	char *prog)
{
	fprintf(stderr, "Usage: %s ", prog);
	fprintf(stderr, " [-a attrname] [-b bufsz] [-v]");
	fprintf(stderr, " [-q] 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_attrname_t	*dmattrp = NULL;
	int		verbose = V_PRINT;

	Progname = argv[0];
	memset(&dmattr, 0, sizeof(dmattr));

	while ((c = getopt(argc, argv, "a:b:vq")) != 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);
			dmattrp = &dmattr;
			break;
		case 'b':
			bufsz = atoi(optarg);
			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);
	}

	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, dmattrp, bufsz, 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(
	dm_sessid_t	sid,
	void		*hanp,
	size_t		hlen,
	dm_attrname_t	*dm_attrp,
	int		verbose)
{
	size_t	rlen;
	size_t	buflen = 10000;
	char	buf[buflen];

	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 (dm_get_dmattr(sid, hanp, hlen, DM_NO_TOKEN, dm_attrp,
				  buflen, (char*)buf, &rlen)) {
			if (verbose & V_PRINT) {
				if( errno == E2BIG ){
					printf("E2BIG\n");
				}
				else if (errno == ENOMEM){
					printf("ENOMEM\n");
				}
				else {
					printf("<none>\n");
				}
			}
		}
		else if (verbose & V_PRINT) {
			if( isalpha(buf[0]) )
				printf("(%s)\n", buf);
			else
				printf("<len=%d>\n",rlen);
		}
	}
}

/*
 * 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_attrname_t	*dmattrp,
	size_t		buflen,
	int		verbose)
{
	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 */
	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_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 (verbose & V_VERBOSE)
			fprintf(stderr, "BULKATTR more=%d, rlen=%d\n", more, 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)) {
				hanp = DM_GET_VALUE(sbuf, dt_handle, void *);
				hlen = DM_GET_LEN(sbuf, dt_handle);

				if (dmattrp) {
					my_print_victim(sid, hanp, hlen,
							dmattrp, verbose);
				}
				else if (verbose & V_PRINT){
					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);
}