xfs: test fallocate ops when rt extent size is and isn't a power of 2
[xfstests-dev.git] / dmapi / src / common / lib / print.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6
7 #include <sys/types.h>
8 #include <sys/param.h>
9 #include <sys/stat.h>
10
11 #include <ctype.h>
12
13 #include <lib/hsm.h>
14
15 #include <string.h>
16
17   /*
18    * Define some standard formats for the printf statements below.
19    */
20
21 #define HDR  "type=%s token=%d sequence=%d\n"
22 #define VALS "\t%s=%s\n"
23 #define VALD "\t%s=%d\n"
24 #define VALLLD "\t%s=%lld\n"
25
26
27 /*
28         Convert a mode_t field into a printable string.
29
30         Returns non-zero if the mode_t is invalid.  The string is
31         returned in *ptr, whether there is an error or not.
32 */
33
34 int
35 format_mode(
36         mode_t  mode,
37         char    **ptr)
38 {
39 static  char    modestr[100];
40         char    *typestr;
41         int     error = 0;
42
43         if     (S_ISFIFO(mode)) typestr = "FIFO";
44         else if(S_ISCHR (mode)) typestr = "Character Device";
45         else if(S_ISBLK (mode)) typestr = "Block Device";
46         else if(S_ISDIR (mode)) typestr = "Directory";
47         else if(S_ISREG (mode)) typestr = "Regular File";
48         else if(S_ISLNK (mode)) typestr = "Symbolic Link";
49         else if(S_ISSOCK(mode)) typestr = "Socket";
50         else {
51                 typestr = "<unknown type>"; 
52                 error++;
53         }
54
55         sprintf(modestr, "mode %06o: perm %c%c%c %c%c%c %c%c%c %c%c%c, type %s",
56                 mode,
57                 mode & S_ISUID ? 's':' ',
58                 mode & S_ISGID ? 'g':' ',
59                 mode & S_ISVTX ? 't':' ',
60                 mode & S_IRUSR ? 'r':'-',
61                 mode & S_IWUSR ? 'w':'-',
62                 mode & S_IXUSR ? 'x':'-',
63                 mode & S_IRGRP ? 'r':'-',
64                 mode & S_IWGRP ? 'w':'-',
65                 mode & S_IXGRP ? 'x':'-',
66                 mode & S_IROTH ? 'r':'-',
67                 mode & S_IWOTH ? 'w':'-',
68                 mode & S_IXOTH ? 'x':'-',
69                 typestr);
70         *ptr = modestr;
71         return(error);
72 }
73
74
75 void
76 print_one_mount_event(
77         void            *msg)
78 {
79         void            *hanp1, *hanp2, *hanp3;
80         size_t          hlen1, hlen2, hlen3;
81         char            hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR];
82         void            *namp1, *namp2;
83         size_t          nlen1, nlen2;
84         char            nams1[NAME_MAX + 1], nams2[NAME_MAX + 1];
85         mode_t          mode;
86
87 #if     VERITAS_21
88         dm_namesp_event_t  *msg_ne = (dm_namesp_event_t *)msg;
89
90 /*
91         msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
92 */
93         hanp1  = DM_GET_VALUE(msg_ne, ne_handle1, void *);
94         hlen1  = DM_GET_LEN  (msg_ne, ne_handle1);
95         hanp2  = DM_GET_VALUE(msg_ne, ne_handle2, void *);
96         hlen2  = DM_GET_LEN  (msg_ne, ne_handle2);
97         namp1  = DM_GET_VALUE(msg_ne, ne_name1, void *);
98         nlen1  = DM_GET_LEN  (msg_ne, ne_name1);
99         namp2  = DM_GET_VALUE(msg_ne, ne_name2, void *);
100         nlen2  = DM_GET_LEN  (msg_ne, ne_name2);
101         hanp3  = NULL;
102         hlen3  = 0;
103         mode   = msg_ne->ne_mode;
104 #else
105         dm_mount_event_t  *msg_me = (dm_mount_event_t *)msg;
106
107         hanp1 = DM_GET_VALUE(msg_me, me_handle1, void *);
108         hlen1 = DM_GET_LEN(msg_me, me_handle1);
109         hanp2 = DM_GET_VALUE(msg_me, me_handle2, void *);
110         hlen2 = DM_GET_LEN(msg_me, me_handle2);
111         namp1  = DM_GET_VALUE(msg_me, me_name1, void *);
112         nlen1 = DM_GET_LEN(msg_me, me_name1);
113         namp2 = DM_GET_VALUE(msg_me, me_name2, void *);
114         nlen2 = DM_GET_LEN(msg_me, me_name2);
115         hanp3 = DM_GET_VALUE(msg_me, me_roothandle, void *);
116         hlen3 = DM_GET_LEN(msg_me, me_roothandle);
117         mode  = msg_me->me_mode;
118 #endif  /* VERITAS_21 */
119
120         if (hanp1 && hlen1) {
121                 hantoa(hanp1, hlen1, hans1);
122         } else {
123                 sprintf(hans1, "<BAD HANDLE, hlen %zd>", hlen1);
124         }
125         if (hanp2 && hlen2) {
126                 hantoa(hanp2, hlen2, hans2);
127         } else {
128                 sprintf(hans2, "<BAD HANDLE, hlen %zd>", hlen2);
129         }
130         if (hanp3 && hlen3) {
131                 hantoa(hanp3, hlen3, hans3);
132         } else {
133                 sprintf(hans3, "<BAD HANDLE, hlen %zd>", hlen3);
134         }
135         if (namp1 && nlen1) {
136                 strncpy(nams1, namp1, nlen1);
137                 if (nlen1 != sizeof(nams1))
138                         nams1[nlen1] = '\0';
139         } else {
140                 sprintf(nams1, "<BAD STRING, nlen %zd>", nlen1);
141         }
142         if (namp2 && nlen2) {
143                 strncpy(nams2, namp2, nlen2);
144                 if (nlen2 != sizeof(nams2))
145                         nams2[nlen2] = '\0';
146         } else {
147                 sprintf(nams2, "<BAD STRING, nlen %zd>", nlen2);
148         }
149
150         printf(VALS VALS VALS VALS VALS VALD,
151              "fs handle",       hans1,
152              "mtpt handle",     hans2,
153              "mtpt path",       nams1,
154              "media desig",     nams2,
155              "root handle",     hans3,
156              "mode",            mode);
157 }
158
159
160 static int
161 print_one_data_event(
162         dm_data_event_t *msg_de)
163 {
164         char            handle[HANDLE_STR];
165         void            *hanp;
166         size_t          hlen;
167
168         hanp  = DM_GET_VALUE(msg_de, de_handle, void *);
169         hlen  = DM_GET_LEN  (msg_de, de_handle);
170
171         if (hanp && hlen) {
172                 hantoa(hanp, hlen, handle);
173         } else {
174                 sprintf(handle, "<BAD HANDLE, hlen %zd>", hlen);
175         }
176
177         printf(VALS VALLLD VALLLD,
178                 "file_handle",  handle,
179                 "offset", (long long) msg_de->de_offset,
180                 "length", (long long) msg_de->de_length);
181
182         return(0);
183 }
184
185
186 int
187 print_one_message(
188         dm_eventmsg_t   *msg)
189 {
190         int             pkt_error = 0;
191         dm_namesp_event_t  *msg_ne;
192         void            *hanp1, *hanp2, *namp1, *namp2;
193         u_int           hlen1, hlen2, nlen1, nlen2;
194         char            hans1[HANDLE_STR], hans2[HANDLE_STR];
195         char            nams1[NAME_MAX + 1], nams2[NAME_MAX + 1];
196
197         /***** USER EVENTS *****/
198
199         if (msg->ev_type == DM_EVENT_USER) {
200     char        *privp;
201     u_int       plen, i;
202
203     printf(HDR,
204                 "user", msg->ev_token, msg->ev_sequence);
205
206     /* print private data as ascii or hex if it exists DM_CONFIG_MAX_MESSAGE_DATA */
207
208     privp = DM_GET_VALUE(msg, ev_data, char *);
209     plen  = DM_GET_LEN  (msg, ev_data);
210     if (plen) {
211         for (i = 0; i < plen; i++) {
212                 if (!isprint(privp[i]) && !isspace(privp[i]))
213                         break;
214         }
215         if (i == plen - 1 && privp[i] == '\0') {
216           printf(VALS,
217                         "privdata", privp);
218         } else {
219           printf("\t%-15s ", "privdata");
220           for (i = 0; i < plen; i++) {
221             printf("%.2x", privp[i]);
222           }
223           printf("\n");
224         }
225     } else {
226         printf(VALS,
227                 "privdata", "<NONE>");
228     }
229
230         /***** CANCEL EVENT *****/
231
232 /* Not implemented on SGI or Veritas */
233
234         } else if (msg->ev_type == DM_EVENT_CANCEL) {
235                 dm_cancel_event_t       *msg_ce;
236
237                 msg_ce = DM_GET_VALUE(msg, ev_data, dm_cancel_event_t *);
238                 printf(HDR VALD VALD,
239                         "cancel", msg->ev_token, msg->ev_sequence,
240                         "sequence", msg_ce->ce_sequence,
241                         "token", msg_ce->ce_token);
242
243         /***** DATA EVENTS *****/
244
245         } else if (msg->ev_type == DM_EVENT_READ ||
246                    msg->ev_type == DM_EVENT_WRITE ||
247                    msg->ev_type == DM_EVENT_TRUNCATE) {
248                 dm_data_event_t *msg_de;
249
250                 msg_de = DM_GET_VALUE(msg, ev_data, dm_data_event_t *);
251
252                 switch (msg->ev_type) {
253                 case DM_EVENT_READ:
254                         printf(HDR, "read", msg->ev_token, msg->ev_sequence);
255                         break;
256
257                 case DM_EVENT_WRITE:
258                         printf(HDR, "write", msg->ev_token, msg->ev_sequence);
259                         break;
260
261                 case DM_EVENT_TRUNCATE:
262                         printf(HDR, "truncate", msg->ev_token,
263                                 msg->ev_sequence);
264                         break;
265                 default: break;
266                 }
267                 print_one_data_event(msg_de);
268
269   /***** DESTROY EVENT *****/
270
271         } else if (msg->ev_type == DM_EVENT_DESTROY) {
272     dm_destroy_event_t  *msg_ds;
273     char                attrname[DM_ATTR_NAME_SIZE + 1];
274     u_char              *copy;
275     u_int               clen;
276     u_int               i;
277
278     msg_ds= DM_GET_VALUE(msg, ev_data, dm_destroy_event_t *);
279     hanp1  = DM_GET_VALUE(msg_ds, ds_handle, void *);
280     hlen1  = DM_GET_LEN  (msg_ds, ds_handle);
281     if (hanp1 && hlen1) {
282       hantoa(hanp1, hlen1, hans1);
283     } else {
284       sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
285     }
286     if (msg_ds->ds_attrname.an_chars[0] != '\0') {
287       strncpy(attrname, (char *)msg_ds->ds_attrname.an_chars, sizeof(attrname));
288     } else {
289       strcpy(attrname, "<NONE>");
290     }
291     printf(HDR VALS VALS,
292              "destroy", msg->ev_token, msg->ev_sequence,
293              "handle",          hans1,
294              "attrname",        attrname);
295     copy  = DM_GET_VALUE(msg_ds, ds_attrcopy, u_char *);
296     clen  = DM_GET_LEN  (msg_ds, ds_attrcopy);
297     if (copy && clen) {
298       printf("\t%-15s ", "attrcopy");
299       for (i = 0; i < clen; i++) {
300         printf("%.2x", copy[i]);
301       }
302       printf("\n");
303     } else {
304       printf(VALS, "attrcopy", "<NONE>");
305     }
306
307   /***** MOUNT EVENT *****/
308
309         } else if (msg->ev_type == DM_EVENT_MOUNT) {
310                 void    *msg_body;
311
312                 printf(HDR, "mount", msg->ev_token, msg->ev_sequence);
313 #if     !VERITAS_21
314                 msg_body = DM_GET_VALUE(msg, ev_data, dm_mount_event_t *);
315 #else   /* VERITAS_21 */
316                 msg_body = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
317 #endif  /* VERITAS_21 */
318                 print_one_mount_event(msg_body);
319
320   /***** NAMESPACE EVENTS *****/
321
322         } else {
323     char        *type;
324
325     msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
326     hanp1  = DM_GET_VALUE(msg_ne, ne_handle1, void *);
327     hlen1  = DM_GET_LEN  (msg_ne, ne_handle1);
328     hanp2  = DM_GET_VALUE(msg_ne, ne_handle2, void *);
329     hlen2  = DM_GET_LEN  (msg_ne, ne_handle2);
330     namp1  = DM_GET_VALUE(msg_ne, ne_name1, void *);
331     nlen1  = DM_GET_LEN  (msg_ne, ne_name1);
332     namp2  = DM_GET_VALUE(msg_ne, ne_name2, void *);
333     nlen2  = DM_GET_LEN  (msg_ne, ne_name2);
334
335     if (hanp1 && hlen1) {
336       hantoa(hanp1, hlen1, hans1);
337     }
338     if (hanp2 && hlen2) {
339       hantoa(hanp2, hlen2, hans2);
340     }
341     if (namp1 && nlen1) {
342       strncpy(nams1, namp1, nlen1);
343       if (nlen1 != sizeof(nams1))
344         nams1[nlen1] = '\0';
345     }
346     if (namp2 && nlen2) {
347       strncpy(nams2, namp2, nlen2);
348       if (nlen2 != sizeof(nams2))
349         nams2[nlen2] = '\0';
350     }
351
352     if (msg->ev_type == DM_EVENT_PREUNMOUNT ||
353         msg->ev_type == DM_EVENT_UNMOUNT) {
354       if (msg_ne->ne_mode == 0) {
355         type = "NOFORCE";
356 #if     !VERITAS_21
357       } else if (msg_ne->ne_mode == DM_UNMOUNT_FORCE) {
358 #else
359       } else if (msg_ne->ne_mode > 0) {
360 #endif
361         type = "FORCE";
362       } else {
363         type = "UNKNOWN";
364         pkt_error++;
365       }
366     } else if (msg->ev_type == DM_EVENT_CREATE ||
367                msg->ev_type == DM_EVENT_POSTCREATE ||
368                msg->ev_type == DM_EVENT_REMOVE ||
369                msg->ev_type == DM_EVENT_POSTREMOVE) {
370         if (format_mode(msg_ne->ne_mode, &type)) {
371           pkt_error++;
372         }
373     }
374
375     switch(msg->ev_type) {
376
377     case DM_EVENT_PREUNMOUNT:
378       printf(HDR VALS VALS VALS,
379              "preunmount", msg->ev_token, msg->ev_sequence,
380              "fs handle",       hans1,
381              "root dir",        hans2,
382              "unmount mode",    type);
383       break;
384
385     case DM_EVENT_UNMOUNT:
386       printf(HDR VALS VALS VALD,
387              "unmount", msg->ev_token, msg->ev_sequence,
388              "fs handle",       hans1,
389              "unmount mode",    type,
390              "retcode",         msg_ne->ne_retcode);
391       break;
392
393     case DM_EVENT_NOSPACE:
394       printf(HDR VALS,
395              "nospace", msg->ev_token, msg->ev_sequence,
396              "fs handle",       hans1);
397       break;
398
399     case DM_EVENT_DEBUT:                /* not supported on SGI */
400       printf(HDR VALS,
401              "debut", msg->ev_token, msg->ev_sequence,
402              "object",          hans1);
403       break;
404
405     case DM_EVENT_CREATE:
406       printf(HDR VALS VALS VALS,
407              "create", msg->ev_token, msg->ev_sequence,
408              "parent dir",      hans1,
409              "name",            nams1,
410              "mode bits",       type);
411       break;
412
413     case DM_EVENT_POSTCREATE:
414       printf(HDR VALS VALS VALS VALS VALD,
415              "postcreate", msg->ev_token, msg->ev_sequence,
416              "parent dir",      hans1,
417              "new object",      hans2,
418              "name",            nams1,
419              "mode bits",       type,
420              "retcode",         msg_ne->ne_retcode);
421       break;
422
423     case DM_EVENT_REMOVE:
424       printf(HDR VALS VALS VALS,
425              "remove", msg->ev_token, msg->ev_sequence,
426              "parent dir",      hans1,
427              "name",            nams1,
428              "mode bits",       type);
429       break;
430
431     case DM_EVENT_POSTREMOVE:
432       printf(HDR VALS VALS VALS VALD,
433              "postremove", msg->ev_token, msg->ev_sequence,
434              "parent dir",      hans1,
435              "name",            nams1,
436              "mode bits",       type,
437              "retcode",         msg_ne->ne_retcode);
438       break;
439
440     case DM_EVENT_RENAME:
441       printf(HDR VALS VALS VALS VALS,
442              "rename", msg->ev_token, msg->ev_sequence,
443              "old parent",      hans1,
444              "new parent",      hans2,
445              "old name",        nams1,
446              "new name",        nams2);
447       break;
448
449     case DM_EVENT_POSTRENAME:
450       printf(HDR VALS VALS VALS VALS VALD,
451              "postrename", msg->ev_token, msg->ev_sequence,
452              "old parent",      hans1,
453              "new parent",      hans2,
454              "old name",        nams1,
455              "new name",        nams2,
456              "retcode",         msg_ne->ne_retcode);
457       break;
458
459     case DM_EVENT_SYMLINK:
460       printf(HDR VALS VALS VALS,
461              "symlink", msg->ev_token, msg->ev_sequence,
462              "parent dir",      hans1,
463              "name",            nams1,
464              "contents",        nams2);
465       break;
466
467     case DM_EVENT_POSTSYMLINK:
468       printf(HDR VALS VALS VALS VALS VALD,
469              "postsymlink", msg->ev_token, msg->ev_sequence,
470              "parent dir",      hans1,
471              "new object",      hans2,
472              "name",            nams1,
473              "contents",        nams2,
474              "retcode",         msg_ne->ne_retcode);
475       break;
476
477     case DM_EVENT_LINK:
478       printf(HDR VALS VALS VALS,
479              "link", msg->ev_token, msg->ev_sequence,
480              "parent dir",      hans1,
481              "source",          hans2,
482              "name",            nams1);
483       break;
484
485     case DM_EVENT_POSTLINK:
486       printf(HDR VALS VALS VALS VALD,
487              "postlink", msg->ev_token, msg->ev_sequence,
488              "parent dir",      hans1,
489              "source",          hans2,
490              "name",            nams1,
491              "retcode",         msg_ne->ne_retcode);
492       break;
493
494     case DM_EVENT_ATTRIBUTE:
495       printf(HDR VALS,
496              "attribute", msg->ev_token, msg->ev_sequence,
497              "object",          hans1);
498       break;
499
500     case DM_EVENT_CLOSE:        /* not supported on SGI */
501       printf(HDR VALS,
502              "close", msg->ev_token, msg->ev_sequence,
503              "object",          hans1);
504       break;
505
506     default:
507       pkt_error++;
508       printf(HDR VALD,
509              "<UNKNOWN>", msg->ev_token, msg->ev_sequence,
510              "ev_type",         msg->ev_type);
511       break;
512     }
513         }
514         return(pkt_error);
515 }
516
517
518 int
519 handle_message(
520         dm_sessid_t     sid,
521         dm_eventmsg_t   *msg)
522 {
523         dm_response_t   response;
524         int             respond, respcode;
525         int             error = 0;
526
527         if (print_one_message(msg))
528                 error++;
529
530         /* Set the defaults for responding to events. */
531
532         respond = 1;
533         response = DM_RESP_CONTINUE;
534         respcode = 0;
535
536         /***** USER EVENTS *****/
537
538         switch (msg->ev_type) {
539         case DM_EVENT_USER:
540                 if (msg->ev_token == DM_INVALID_TOKEN)
541                         respond = 0;
542                 break;
543
544         case DM_EVENT_CANCEL:
545         case DM_EVENT_DESTROY:
546         case DM_EVENT_POSTCREATE:
547         case DM_EVENT_POSTREMOVE:
548         case DM_EVENT_POSTRENAME:
549         case DM_EVENT_POSTSYMLINK:
550         case DM_EVENT_POSTLINK:
551         case DM_EVENT_ATTRIBUTE:
552         case DM_EVENT_CLOSE:
553                 respond = 0;
554                 break;
555
556         case DM_EVENT_MOUNT:
557         case DM_EVENT_READ:
558         case DM_EVENT_WRITE:
559         case DM_EVENT_TRUNCATE:
560         case DM_EVENT_PREUNMOUNT:
561         case DM_EVENT_UNMOUNT:
562         case DM_EVENT_DEBUT:
563         case DM_EVENT_CREATE:
564         case DM_EVENT_REMOVE:
565         case DM_EVENT_RENAME:
566         case DM_EVENT_SYMLINK:
567         case DM_EVENT_LINK:
568                 break;
569
570         case DM_EVENT_NOSPACE:
571                 response = DM_RESP_ABORT;
572                 respcode = ENOSPC;
573                 break;
574
575         default:
576                 if (msg->ev_token == DM_INVALID_TOKEN)
577                         respond = 0;
578                 break;
579         }
580
581         /* Respond to those messages which require a response. */
582
583         if (respond) {
584                 if (dm_respond_event(sid, msg->ev_token, response, respcode, 0, 0)) {
585                         errno_msg("Can't respond to event");
586                 }
587         }
588         return(error);
589 }