set MR bits on newly-created files.
[xfstests-dev.git] / dmapi / src / sample_hsm / mls.c
1 /*
2  * Simple util to print out DMAPI info about a file
3  *
4  * This code was written by Peter Lawthers, and placed in the public
5  * domain for use by DMAPI implementors and app writers.
6  *
7  * Standard disclaimer:
8  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
12  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
14  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
17  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18  * SUCH DAMAGE.
19  */
20
21 #include <sys/types.h>
22 #include <sys/param.h>
23 #include <sys/stat.h>
24
25 #include <unistd.h>
26 #include <ctype.h>
27 #include <string.h>
28 #include <fcntl.h>
29
30 #include <lib/hsm.h>
31
32 #define MAX_RGNS        8       /* Arbitrary for this release */
33 #define NUM_EXTENTS     4
34
35 extern char     *optarg;
36 extern int       optind, optopt, opterr;
37 char            *Progname;
38
39 void             usage(char *);
40 int              mr_info(dm_sessid_t, void *, size_t);
41 int              alloc_info(dm_sessid_t, void *, size_t);
42 int              event_info(dm_sessid_t, void *, size_t);
43 int              handle_info(dm_sessid_t, void *, size_t);
44
45 extern int       setup_dmapi(dm_sessid_t *);
46 extern void      errno_msg(char *, ...);
47 extern void      print_handle(void *, size_t);
48
49
50 void
51 usage(
52         char *prog)
53 {
54         fprintf(stderr, "Usage: %s <options> filename \n ", prog);
55         fprintf(stderr, "\t-m   managed region info\n");
56         fprintf(stderr, "\t-a   allocation info\n");
57         fprintf(stderr, "\t-e   event info\n");
58         fprintf(stderr, "\t-h   handle\n");
59 }
60
61
62 int
63 main(
64         int     argc, 
65         char    *argv[])
66 {
67         int              c;
68         int              error;
69         int              mr_flag, alloc_flag, handle_flag, event_flag;
70         void            *hanp;
71         size_t           hlen;
72         char            *filename;
73         dm_sessid_t      sid;
74
75
76         Progname = argv[0];
77         mr_flag  = alloc_flag =  handle_flag = event_flag = 0;
78         
79         while ((c = getopt(argc, argv, "maeh")) != EOF) {
80                 switch (c) {
81                 case 'm':
82                         mr_flag = 1;
83                         break;
84                 case 'a':
85                         alloc_flag = 1;
86                         break;
87                 case 'e':
88                         event_flag = 1;
89                         break;
90                 case 'h':
91                         handle_flag = 1;
92                         break;
93                 case '?':
94                 default:
95                         usage(Progname);
96                         exit(1);
97                 }
98         }
99         if (optind >= argc) {
100                 usage(Progname);
101                 exit(1);
102         }
103         filename = argv[optind];
104         if (filename == NULL) {
105                 usage(Progname);
106                 exit(1);
107         }
108         
109
110         /*
111          * Set up our link to the DMAPI, and get a handle for
112          * the file we want to query
113          */
114         error = setup_dmapi(&sid);
115         if (error)
116                 exit(1);
117
118         if (dm_path_to_handle(filename, &hanp, &hlen) == -1) {
119                 printf("Can't get handle for path %s", filename);
120                 error = 1;
121                 goto out;
122         }
123
124         printf("File %s:\n", filename);
125         if (mr_flag) {
126                 error = mr_info(sid, hanp, hlen);
127                 if (error) {
128                         error = 1;
129                         goto out;
130                 }
131         }
132         if (alloc_flag) {
133                 error = alloc_info(sid, hanp, hlen);
134                 if (error) {
135                         error = 1;
136                         goto out;
137                 }
138         }
139         if (event_flag) {
140                 error = event_info(sid, hanp, hlen);
141                 if (error) {
142                         error = 1;
143                         goto out;
144                 }
145         }
146         if (handle_flag) {
147                 error = handle_info(sid, hanp, hlen);
148                 if (error) {
149                         error = 1;
150                         goto out;
151                 }
152         }
153
154 out:
155         if (dm_destroy_session(sid)) {
156                 errno_msg("Can't shut down session");
157                 error = 1;
158         }
159
160         return(error);
161 }
162
163 /*
164  * Get the complete list of all managed regions for a file. For now,
165  * we know that most implementations only support a small number of
166  * regions, so we don't handle the E2BIG error here.
167  */
168 int
169 mr_info(
170         dm_sessid_t      sid,
171         void            *hanp,
172         size_t           hlen)
173 {
174         u_int           i;
175         u_int           ret;
176         dm_region_t     rgn[MAX_RGNS];
177
178         memset((char *)&rgn, 0, (sizeof(dm_region_t) * MAX_RGNS));
179         if (dm_get_region(sid, hanp, hlen, DM_NO_TOKEN, MAX_RGNS, rgn, &ret)) {
180                 errno_msg("Can't get list of managed regions");
181                 return(1);
182         }
183         printf("\n");
184         for (i=0; i<ret; i++) {
185                 printf("\tRegion %d:\n", i);
186                 printf("\t\toffset %lld, ", rgn[i].rg_offset);
187                 printf("size %lld, ", rgn[i].rg_size);
188                 printf("flags 0x%x", rgn[i].rg_flags);
189                 printf(" ( ");
190                 if (rgn[i].rg_flags & DM_REGION_NOEVENT)
191                         printf("noevent ");
192                 if (rgn[i].rg_flags & DM_REGION_READ)
193                         printf("read ");
194                 if (rgn[i].rg_flags & DM_REGION_WRITE)
195                         printf("write ");
196                 if (rgn[i].rg_flags & DM_REGION_TRUNCATE)
197                         printf("trunc ");
198                 printf(" )\n");
199         }
200         return(0);
201 }
202
203 /*
204  * Get the complete list of events for a file.
205  */
206 int
207 event_info(
208         dm_sessid_t      sid,
209         void            *hanp,
210         size_t           hlen)
211 {
212         u_int           ret;
213         dm_eventset_t   eventlist;
214
215         DMEV_ZERO(eventlist);
216         if (dm_get_eventlist(sid, hanp, hlen, DM_NO_TOKEN, DM_EVENT_MAX, 
217                                 &eventlist, &ret)) {
218                 errno_msg("Can't get list of events");
219                 return(1);
220         }
221         printf("\n\tEvent list: \n\t\t");
222         if (DMEV_ISSET(DM_EVENT_MOUNT, eventlist)) 
223                 printf("mount ");
224         if (DMEV_ISSET(DM_EVENT_PREUNMOUNT, eventlist)) 
225                 printf("preunmount ");
226         if (DMEV_ISSET(DM_EVENT_UNMOUNT, eventlist)) 
227                 printf("unmount ");
228         if (DMEV_ISSET(DM_EVENT_DEBUT, eventlist)) 
229                 printf("debut ");
230         if (DMEV_ISSET(DM_EVENT_CREATE, eventlist)) 
231                 printf("create ");
232         if (DMEV_ISSET(DM_EVENT_POSTCREATE, eventlist)) 
233                 printf("postcreate ");
234         if (DMEV_ISSET(DM_EVENT_REMOVE, eventlist)) 
235                 printf("remove ");
236         if (DMEV_ISSET(DM_EVENT_POSTREMOVE, eventlist)) 
237                 printf("postmount ");
238         if (DMEV_ISSET(DM_EVENT_RENAME, eventlist)) 
239                 printf("rename ");
240         if (DMEV_ISSET(DM_EVENT_POSTRENAME, eventlist)) 
241                 printf("postrename ");
242         if (DMEV_ISSET(DM_EVENT_LINK, eventlist)) 
243                 printf("link ");
244         if (DMEV_ISSET(DM_EVENT_POSTLINK, eventlist)) 
245                 printf("postlink ");
246         if (DMEV_ISSET(DM_EVENT_SYMLINK, eventlist)) 
247                 printf("symlink ");
248         if (DMEV_ISSET(DM_EVENT_POSTSYMLINK, eventlist)) 
249                 printf("postsymlink ");
250         if (DMEV_ISSET(DM_EVENT_READ, eventlist)) 
251                 printf("read ");
252         if (DMEV_ISSET(DM_EVENT_WRITE, eventlist)) 
253                 printf("write ");
254         if (DMEV_ISSET(DM_EVENT_TRUNCATE, eventlist)) 
255                 printf("truncate ");
256         if (DMEV_ISSET(DM_EVENT_ATTRIBUTE, eventlist)) 
257                 printf("attribute ");
258         if (DMEV_ISSET(DM_EVENT_DESTROY, eventlist)) 
259                 printf("destroy ");
260         if (DMEV_ISSET(DM_EVENT_NOSPACE, eventlist)) 
261                 printf("nospace ");
262         if (DMEV_ISSET(DM_EVENT_USER, eventlist)) 
263                 printf("user ");
264
265         printf("\n");
266         return(0);
267 }
268
269 /*
270  * Print out the handle for a file
271  */
272 int
273 handle_info(
274         dm_sessid_t      sid,
275         void            *hanp,
276         size_t           hlen)
277 {
278         printf("\n\tHandle (handle length, value) \n\t\t");
279         print_handle(hanp, hlen);
280         return(0);
281 }
282
283 /*
284  * Get the allocation info for a file. We pick some small number
285  * of extents to get the residency info on at one time
286  */
287 int
288 alloc_info(
289         dm_sessid_t      sid,
290         void            *hanp,
291         size_t           hlen)
292 {
293         int             i, more;
294         dm_off_t        offset;
295         u_int           nextents, nret;
296         dm_extent_t     ext[NUM_EXTENTS];
297
298
299         nextents = NUM_EXTENTS;
300         offset   = 0;
301         printf("\n\tAllocation info \n");
302         do {
303                 more = dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, &offset, 
304                                         nextents, ext, &nret);
305                 if (more == -1) {
306                         errno_msg("Can't get alloc info for file");
307                         return(1);
308                 }
309                 for (i=0; i<nret; i++) {
310                         printf("\t\tExtent %d ", i);
311                         if (ext[i].ex_type == DM_EXTENT_RES)
312                                 printf("(resident): ");
313                         if (ext[i].ex_type == DM_EXTENT_HOLE)
314                                 printf("(hole): ");
315                         printf("offset %lld, ", ext[i].ex_offset);
316                         printf("len %lld\n", ext[i].ex_length);
317                 }
318         } while (more == 1);
319         return(0);
320 }