From 99b62f4c7b5f7eacd31666c8d48fdf9c8ae302b9 Mon Sep 17 00:00:00 2001 From: Dean Roehrich Date: Tue, 7 Oct 2003 18:26:55 +0000 Subject: [PATCH] Add DMAPI tests for dm_get_bulkall and dm_get_bulkattr Test for dm_get_bulkall. --- dmapi/src/suite2/src/test_bulkall.c | 308 +++++++++++++++++++++++++++ dmapi/src/suite2/src/test_bulkattr.c | 292 +++++++++++++++++++++++++ 2 files changed, 600 insertions(+) create mode 100644 dmapi/src/suite2/src/test_bulkall.c create mode 100644 dmapi/src/suite2/src/test_bulkattr.c diff --git a/dmapi/src/suite2/src/test_bulkall.c b/dmapi/src/suite2/src/test_bulkall.c new file mode 100644 index 00000000..408113be --- /dev/null +++ b/dmapi/src/suite2/src/test_bulkall.c @@ -0,0 +1,308 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include + +#include + + +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) { + printf("%d (%s)\n", + attrlen, + isalpha(attrval[0]) ? attrval : ""); + } + else { + printf("\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); +} + diff --git a/dmapi/src/suite2/src/test_bulkattr.c b/dmapi/src/suite2/src/test_bulkattr.c new file mode 100644 index 00000000..8b19d542 --- /dev/null +++ b/dmapi/src/suite2/src/test_bulkattr.c @@ -0,0 +1,292 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include + +#include + +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("\n"); + } + } + } + else if (verbose & V_PRINT) { + if( isalpha(buf[0]) ) + printf("(%s)\n", buf); + else + printf("\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); +} + -- 2.25.1