2 * This code was written by Peter Lawthers, and placed in the public
3 * domain for use by DMAPI implementors and app writers.
6 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
7 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
10 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
11 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
12 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18 * October 1, 2003: Dean Roehrich
19 * - Adapted to test dm_get_bulkall, from migfind.c.
34 extern int optind, optopt, opterr;
37 extern void err_msg(char *, ...);
38 extern void errno_msg(char *, ...);
40 int setup_dmapi(dm_sessid_t *);
41 int scan_fs(dm_sessid_t, void *, size_t, dm_attrname_t*, size_t,
49 fprintf(stderr, "Usage: %s ", prog);
50 fprintf(stderr, " <-a attrname> [-b bufsz] [-v] [-q]");
51 fprintf(stderr, " filesystem\n");
55 #define V_VERBOSE 0x02
73 int verbose = V_PRINT;
76 memset(&dmattr, 0, sizeof(dmattr));
78 while ((c = getopt(argc, argv, "a:b:evq")) != EOF) {
81 if (strlen(optarg) > (DM_ATTR_NAME_SIZE-1)){
82 printf("Arg for -a too long\n");
85 strcpy((char*)dmattr.an_chars, optarg);
105 if (optind >= argc) {
109 if (dmattr.an_chars[0] == '\0') {
113 fsname = argv[optind];
116 * Now we have our filesystem name and possibly a size threshold
117 * to look for. Init the dmapi, and get a filesystem handle so
118 * we can scan the filesystem
120 error = setup_dmapi(&sid);
124 if (dm_path_to_fshandle(fsname, &fs_hanp, &fs_hlen) == -1) {
125 errno_msg("Can't get filesystem handle");
130 if( dm_get_config(fs_hanp, fs_hlen, DM_CONFIG_BULKALL, &ret) ||
132 printf("Kernel does not have dm_get_bulkall\n");
137 * Get the attributes of all files in the filesystem
139 error = scan_fs(sid, fs_hanp, fs_hlen, &dmattr, bufsz, extras, verbose);
145 * We're done, so we can shut down our session.
147 if (dm_destroy_session(sid) == -1) {
148 errno_msg("Can't close session");
168 if (hlen > HANDLE_LEN) {
169 if (verbose & V_PRINT)
170 printf("-- invalid length --\n");
173 char handle_str[HANDLE_STR];
174 if (verbose & V_PRINT) {
175 printf("%zd\t", hlen);
176 hantoa(hanp, hlen, handle_str);
177 printf("%s ", handle_str);
180 (long long) sbuf->dt_size);
182 (long long) sbuf->dt_ino);
186 attrval = DM_GET_VALUE(xbuf,
188 attrlen = DM_GET_LEN(xbuf,
190 /* Hmmm, a hole in the dmapi spec.
191 * No way to have a null pointer
192 * for the value. No way to
193 * distinguish between a zero-length
194 * attribute value and not finding
195 * the attribute in the first place.
197 * Punt. Since I cannot get a null
198 * pointer for the value, let's look
199 * at the length. If it's zero,
200 * we'll say the attribute was
203 if (verbose & V_PRINT) {
205 if (isalpha(attrval[0]) )
206 printf("(%s)\n", attrval);
208 printf("<len=%d>\n", attrlen);
218 * Get the attributes for all the files in a filesystem in bulk,
219 * including the specified dmattr,
220 * and print out the handles and dmattr values.
227 dm_attrname_t *dmattr,
232 u_int mask; /* attributes to scan for */
233 dm_xstat_t *dm_xstatbuf, *xbuf; /* attributes buffer */
235 dm_attrloc_t locp; /* opaque location in fs */
236 size_t rlenp; /* ret length of stat info */
237 void *hanp; /* file handle */
238 size_t hlen; /* file handle */
239 int more; /* loop terminator */
246 dm_xstatbuf = (dm_xstat_t *)calloc(1, buflen);
247 if (dm_xstatbuf == NULL) {
248 err_msg("Can't get memory for stat buffer");
254 * Initialize the offset opaque offset cookie that
255 * we use in successive calls to dm_get_bulkattr()
257 error = dm_init_attrloc(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, &locp);
259 errno_msg("%s/%d: Can't initialize offset cookie (%d)", __FILE__, __LINE__, errno);
265 * Set our stat mask so that we'll only get the normal stat(2)
266 * info and the file's handle
268 mask = DM_AT_HANDLE | DM_AT_STAT;
270 more = dm_get_bulkall(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
271 mask, dmattr, &locp, buflen,
272 dm_xstatbuf, &rlenp);
273 if (verbose & V_VERBOSE)
274 fprintf(stderr, "BULKALL more=%d, rlen=%zd\n",
277 errno_msg("%s/%d: Can't get bulkall for filesystem", __FILE__, __LINE__, errno);
282 * Walk through the stat buffer and pull out files
283 * that are of interest
285 * The stat buffer is variable length, so we must
286 * use the DM_STEP_TO_NEXT macro to access each individual
287 * dm_xstat_t structure in the returned buffer.
290 while (xbuf != NULL) {
291 sbuf = &xbuf->dx_statinfo;
292 if (S_ISREG(sbuf->dt_mode)) {
293 hanp = DM_GET_VALUE(sbuf, dt_handle, void *);
294 hlen = DM_GET_LEN(sbuf, dt_handle);
296 my_print_victim(hanp, hlen, xbuf, sbuf,
299 /* The sbuf has the offset to the next xbuf */
300 xbuf = DM_STEP_TO_NEXT(sbuf, dm_xstat_t *);