9 * Monitor all events for a file system.
10 * When one arrives, print a message with all the details.
11 * If the message is synchronous, always reply with DM_RESP_CONTINUE
12 * (This program doesn't perform any real file system or HSM work.)
14 * This is a simplification of the "migin.c" example program.
15 * The original code was by Peter Lawthers:
16 * This code was written by Peter Lawthers, and placed in the public
17 * domain for use by DMAPI implementors and app writers.
25 #include <sys/types.h>
27 #include <sys/resource.h>
29 #include <sys/param.h>
35 * Define some standard formats for the printf statements below.
38 #define HDR "%s: token %d sequence %d\n"
39 #define VALS "\t%-15s %s\n"
40 #define VALD "\t%-15s %d\n"
42 #define VALLLD "\t%-15s %lld\n"
44 #define VALLLD "\t%-15s %ld\n"
51 int main (int, char **);
52 static void event_loop (dm_sessid_t, int);
53 int handle_message (dm_sessid_t, dm_eventmsg_t *);
54 static int format_mode(mode_t mode, char **ptr);
55 static int get_fs_handle (char *, void **, size_t *);
56 static int set_disposition(dm_sessid_t, void *, size_t);
57 static int set_events (dm_sessid_t, void *, size_t);
58 static int clear_events (dm_sessid_t, void *, size_t);
59 int finish_responding(dm_sessid_t);
60 int establish_handler(void);
61 void exit_handler (int);
63 #define MAXNAMELEN 256
66 * Keep these global so the exit_handler and err_msg routines can get to them
72 dm_sessid_t oldsid = 0;
80 fprintf(stderr, "Usage: %s ", prog);
81 fprintf(stderr, " <-S oldsid> <-v verbose> ");
82 fprintf(stderr, "filesystem \n");
98 /* Progname = argv[0];*/ Progname = "print_event";
101 while ((c = getopt(argc, argv, "vs:S:")) != EOF) {
104 Sleep = atoi(optarg);
107 oldsid = atoi(optarg);
118 if (optind >= argc) {
122 fsname = argv[optind];
123 if (fsname == NULL) {
129 * Establish an exit handler
131 error = establish_handler();
136 * Init the dmapi, and get a filesystem handle so
137 * we can set up our events
143 error = setup_dmapi(&sid);
148 error = get_fs_handle(fsname, &fs_hanp, &fs_hlen);
153 * Set the event disposition so that our session will receive
154 * all the events for the given file system
156 error = set_disposition(sid, fs_hanp, fs_hlen);
161 * Enable monitoring for all events in the given file system
163 error = set_events(sid, fs_hanp, fs_hlen);
168 * Now sit in an infinite loop, reporting on any events that occur.
169 * The program is exited after a signal through exit_handler().
172 event_loop(sid, 1 /*waitflag*/);
175 * If we get here, cleanup after the event_loop failure
184 * Main event loop processing
186 * The waitflag argument is set to 1 when we call this from main().
187 * In this case, continuously process incoming events,
188 * blocking if there are none available.
189 * In the exit_handler(), call this routine with waitflag=0.
190 * Just try to read the events once in this case with no blocking.
205 * We take a swag at a buffer size. If it's wrong, we can
209 bufsize = sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + HANDLE_LEN;
211 msgbuf = (void *)malloc(bufsize);
212 if (msgbuf == NULL) {
213 err_msg("Can't allocate memory for buffer");
218 error = dm_get_events(sid, ALL_AVAIL_MSGS,
219 waitflag ? DM_EV_WAIT:0, bufsize, msgbuf, &bufsize);
221 if (errno == EAGAIN) {
226 if (errno == E2BIG) {
228 msgbuf = (void *)malloc(bufsize);
229 if (msgbuf == NULL) {
230 err_msg("Can't resize msg buffer");
235 errno_msg("Error getting events from DMAPI (%d)", errno);
240 * Walk through the message buffer, pull out each individual
241 * message, and dispatch the messages to handle_message(),
242 * which will respond to the events.
246 msg = (dm_eventmsg_t *)msgbuf;
247 while (msg != NULL ) {
249 error = handle_message(sid, msg);
254 msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *);
256 if (count != 1 && Verbose) {
257 err_msg("Found %d events in one call to "
258 "dm_get_events\n", count);
267 print_one_mount_event(
270 void *hanp1, *hanp2, *hanp3;
271 size_t hlen1, hlen2, hlen3;
272 char hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR];
275 char nams1[MAXNAMELEN], nams2[MAXNAMELEN];
279 dm_namesp_event_t *msg_ne = (dm_namesp_event_t *)msg;
282 msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
284 hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *);
285 hlen1 = DM_GET_LEN (msg_ne, ne_handle1);
286 hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *);
287 hlen2 = DM_GET_LEN (msg_ne, ne_handle2);
288 namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *);
289 nlen1 = DM_GET_LEN (msg_ne, ne_name1);
290 namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *);
291 nlen2 = DM_GET_LEN (msg_ne, ne_name2);
294 mode = msg_ne->ne_mode;
296 dm_mount_event_t *msg_me = (dm_mount_event_t *)msg;
298 hanp1 = DM_GET_VALUE(msg_me, me_handle1, void *);
299 hlen1 = DM_GET_LEN(msg_me, me_handle1);
300 hanp2 = DM_GET_VALUE(msg_me, me_handle2, void *);
301 hlen2 = DM_GET_LEN(msg_me, me_handle2);
302 namp1 = DM_GET_VALUE(msg_me, me_name1, void *);
303 nlen1 = DM_GET_LEN(msg_me, me_name1);
304 namp2 = DM_GET_VALUE(msg_me, me_name2, void *);
305 nlen2 = DM_GET_LEN(msg_me, me_name2);
306 hanp3 = DM_GET_VALUE(msg_me, me_roothandle, void *);
307 hlen3 = DM_GET_LEN(msg_me, me_roothandle);
308 mode = msg_me->me_mode;
309 #endif /* VERITAS_21 */
311 if (hanp1 && hlen1) {
312 hantoa(hanp1, hlen1, hans1);
314 sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
316 if (hanp2 && hlen2) {
317 hantoa(hanp2, hlen2, hans2);
319 sprintf(hans2, "<BAD HANDLE, hlen %d>", hlen2);
321 if (hanp3 && hlen3) {
322 hantoa(hanp3, hlen3, hans3);
324 sprintf(hans3, "<BAD HANDLE, hlen %d>", hlen3);
326 if (namp1 && nlen1) {
327 strncpy(nams1, namp1, nlen1);
328 if (nlen1 != sizeof(nams1))
331 sprintf(nams1, "<BAD STRING, nlen %d>", nlen1);
333 if (namp2 && nlen2) {
334 strncpy(nams2, namp2, nlen2);
335 if (nlen2 != sizeof(nams2))
338 sprintf(nams2, "<BAD STRING, nlen %d>", nlen2);
341 printf(VALS VALS VALS VALS VALS VALD,
343 "mtpt handle", hans2,
345 "media desig", nams2,
346 "root handle", hans3,
352 * First, weed out the events which return interesting structures.
353 * If it's not one of those, unpack the dm_namesp_event structure
354 * and display the contents.
363 dm_response_t response;
364 int respond, respcode;
365 dm_namesp_event_t *msg_ne;
367 dm_mount_event_t *msg_me;
369 void *hanp1, *hanp2, *namp1, *namp2;
370 u_int hlen1, hlen2, nlen1, nlen2;
371 char hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR];
372 char nams1[MAXNAMELEN], nams2[MAXNAMELEN];
375 * Set the defaults for responding to events
378 response = DM_RESP_CONTINUE;
381 /***** USER EVENTS *****/
383 if (msg->ev_type == DM_EVENT_USER) {
388 "user", msg->ev_token, msg->ev_sequence);
390 /* print private data as ascii or hex if it exists DM_CONFIG_MAX_MESSAGE_DATA */
392 privp = DM_GET_VALUE(msg, ev_data, char *);
393 plen = DM_GET_LEN (msg, ev_data);
395 for (i = 0; i < plen; i++) {
396 if (!isprint(privp[i]) && !isspace(privp[i]))
399 if (i == plen - 1 && privp[i] == '\0') {
403 printf("\t%-15s ", "privdata");
404 for (i = 0; i < plen; i++) {
405 printf("%.2x", privp[i]);
411 "privdata", "<NONE>");
414 if (msg->ev_token == DM_INVALID_TOKEN) /* async dm_send_msg event */
418 /***** CANCEL EVENT *****/
420 /* Not implemented on SGI or Veritas */
422 else if (msg->ev_type == DM_EVENT_CANCEL) {
423 dm_cancel_event_t *msg_ce;
425 msg_ce = DM_GET_VALUE(msg, ev_data, dm_cancel_event_t *);
426 printf(HDR VALD VALD,
427 "cancel", msg->ev_token, msg->ev_sequence,
428 "sequence", msg_ce->ce_sequence,
429 "token", msg_ce->ce_token);
433 /***** DATA EVENTS *****/
435 else if (msg->ev_type == DM_EVENT_READ ||
436 msg->ev_type == DM_EVENT_WRITE ||
437 msg->ev_type == DM_EVENT_TRUNCATE) {
438 dm_data_event_t *msg_de;
440 msg_de = DM_GET_VALUE(msg, ev_data, dm_data_event_t *);
441 hanp1 = DM_GET_VALUE(msg_de, de_handle, void *);
442 hlen1 = DM_GET_LEN (msg_de, de_handle);
443 if (hanp1 && hlen1) {
444 hantoa(hanp1, hlen1, hans1);
446 sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
449 switch(msg->ev_type) {
452 printf(HDR VALS VALLLD VALLLD,
453 "read", msg->ev_token, msg->ev_sequence,
454 "file handle", hans1,
455 "offset", msg_de->de_offset,
456 "length", msg_de->de_length);
460 printf(HDR VALS VALLLD VALLLD,
461 "write", msg->ev_token, msg->ev_sequence,
462 "file handle", hans1,
463 "offset", msg_de->de_offset,
464 "length", msg_de->de_length);
467 case DM_EVENT_TRUNCATE:
468 printf(HDR VALS VALLLD VALLLD,
469 "truncate", msg->ev_token, msg->ev_sequence,
470 "file handle", hans1,
471 "offset", msg_de->de_offset,
472 "length", msg_de->de_length);
477 /***** DESTROY EVENT *****/
479 else if (msg->ev_type == DM_EVENT_DESTROY) {
480 dm_destroy_event_t *msg_ds;
481 char attrname[DM_ATTR_NAME_SIZE + 1];
486 msg_ds= DM_GET_VALUE(msg, ev_data, dm_destroy_event_t *);
487 hanp1 = DM_GET_VALUE(msg_ds, ds_handle, void *);
488 hlen1 = DM_GET_LEN (msg_ds, ds_handle);
489 if (hanp1 && hlen1) {
490 hantoa(hanp1, hlen1, hans1);
492 sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
494 if (msg_ds->ds_attrname.an_chars[0] != '\0') {
495 strncpy(attrname, (char *)msg_ds->ds_attrname.an_chars, sizeof(attrname));
497 strcpy(attrname, "<NONE>");
499 printf(HDR VALS VALS,
500 "destroy", msg->ev_token, msg->ev_sequence,
502 "attrname", attrname);
503 copy = DM_GET_VALUE(msg_ds, ds_attrcopy, u_char *);
504 clen = DM_GET_LEN (msg_ds, ds_attrcopy);
506 printf("\t%-15s ", "attrcopy");
507 for (i = 0; i < clen; i++) {
508 printf("%.2x", copy[i]);
512 printf(VALS, "attrcopy", "<NONE>");
517 /***** MOUNT EVENT *****/
519 else if (msg->ev_type == DM_EVENT_MOUNT) {
520 printf(HDR, "mount", msg->ev_token, msg->ev_sequence);
522 msg_me = DM_GET_VALUE(msg, ev_data, dm_mount_event_t *);
523 print_one_mount_event(msg_me);
524 #else /* VERITAS_21 */
525 msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
526 print_one_mount_event(msg_ne);
527 #endif /* VERITAS_21 */
530 /***** NAMESPACE EVENTS *****/
535 msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
536 hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *);
537 hlen1 = DM_GET_LEN (msg_ne, ne_handle1);
538 hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *);
539 hlen2 = DM_GET_LEN (msg_ne, ne_handle2);
540 namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *);
541 nlen1 = DM_GET_LEN (msg_ne, ne_name1);
542 namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *);
543 nlen2 = DM_GET_LEN (msg_ne, ne_name2);
545 if (hanp1 && hlen1) {
546 hantoa(hanp1, hlen1, hans1);
548 if (hanp2 && hlen2) {
549 hantoa(hanp2, hlen2, hans2);
551 if (namp1 && nlen1) {
552 strncpy(nams1, namp1, nlen1);
553 if (nlen1 != sizeof(nams1))
556 if (namp2 && nlen2) {
557 strncpy(nams2, namp2, nlen2);
558 if (nlen2 != sizeof(nams2))
562 if (msg->ev_type == DM_EVENT_PREUNMOUNT ||
563 msg->ev_type == DM_EVENT_UNMOUNT) {
564 if (msg_ne->ne_mode == 0) {
567 } else if (msg_ne->ne_mode == DM_UNMOUNT_FORCE) {
569 } else if (msg_ne->ne_mode > 0) {
576 } else if (msg->ev_type == DM_EVENT_CREATE ||
577 msg->ev_type == DM_EVENT_POSTCREATE ||
578 msg->ev_type == DM_EVENT_REMOVE ||
579 msg->ev_type == DM_EVENT_POSTREMOVE) {
580 if (format_mode(msg_ne->ne_mode, &type)) {
585 switch(msg->ev_type) {
587 case DM_EVENT_PREUNMOUNT:
588 printf(HDR VALS VALS VALS,
589 "preunmount", msg->ev_token, msg->ev_sequence,
592 "unmount mode", type);
595 case DM_EVENT_UNMOUNT:
596 printf(HDR VALS VALS VALD,
597 "unmount", msg->ev_token, msg->ev_sequence,
599 "unmount mode", type,
600 "retcode", msg_ne->ne_retcode);
603 case DM_EVENT_NOSPACE:
605 "nospace", msg->ev_token, msg->ev_sequence,
607 response = DM_RESP_ABORT;
611 case DM_EVENT_DEBUT: /* not supported on SGI */
613 "debut", msg->ev_token, msg->ev_sequence,
617 case DM_EVENT_CREATE:
618 printf(HDR VALS VALS VALS,
619 "create", msg->ev_token, msg->ev_sequence,
625 case DM_EVENT_POSTCREATE:
626 printf(HDR VALS VALS VALS VALS VALD,
627 "postcreate", msg->ev_token, msg->ev_sequence,
632 "retcode", msg_ne->ne_retcode);
636 case DM_EVENT_REMOVE:
637 printf(HDR VALS VALS VALS,
638 "remove", msg->ev_token, msg->ev_sequence,
644 case DM_EVENT_POSTREMOVE:
645 printf(HDR VALS VALS VALS VALD,
646 "postremove", msg->ev_token, msg->ev_sequence,
650 "retcode", msg_ne->ne_retcode);
654 case DM_EVENT_RENAME:
655 printf(HDR VALS VALS VALS VALS,
656 "rename", msg->ev_token, msg->ev_sequence,
663 case DM_EVENT_POSTRENAME:
664 printf(HDR VALS VALS VALS VALS VALD,
665 "postrename", msg->ev_token, msg->ev_sequence,
670 "retcode", msg_ne->ne_retcode);
674 case DM_EVENT_SYMLINK:
675 printf(HDR VALS VALS VALS,
676 "symlink", msg->ev_token, msg->ev_sequence,
682 case DM_EVENT_POSTSYMLINK:
683 printf(HDR VALS VALS VALS VALS VALD,
684 "postsymlink", msg->ev_token, msg->ev_sequence,
689 "retcode", msg_ne->ne_retcode);
694 printf(HDR VALS VALS VALS,
695 "link", msg->ev_token, msg->ev_sequence,
701 case DM_EVENT_POSTLINK:
702 printf(HDR VALS VALS VALS VALD,
703 "postlink", msg->ev_token, msg->ev_sequence,
707 "retcode", msg_ne->ne_retcode);
711 case DM_EVENT_ATTRIBUTE:
713 "attribute", msg->ev_token, msg->ev_sequence,
718 case DM_EVENT_CLOSE: /* not supported on SGI */
720 "close", msg->ev_token, msg->ev_sequence,
728 "<UNKNOWN>", msg->ev_token, msg->ev_sequence,
729 "ev_type", msg->ev_type);
730 if (msg->ev_token == DM_INVALID_TOKEN)
737 * Now respond to those messages which require a response
740 error = dm_respond_event(sid, msg->ev_token, response, respcode, 0, 0);
742 errno_msg("Can't respond to event");
746 err_msg("Sleeping for %d seconds!\n", Sleep);
756 Convert a mode_t field into a printable string.
758 Returns non-zero if the mode_t is invalid. The string is
759 returned in *ptr, whether there is an error or not.
767 static char modestr[100];
771 if (S_ISFIFO(mode)) typestr = "FIFO";
772 else if(S_ISCHR (mode)) typestr = "Character Device";
773 else if(S_ISBLK (mode)) typestr = "Block Device";
774 else if(S_ISDIR (mode)) typestr = "Directory";
775 else if(S_ISREG (mode)) typestr = "Regular File";
776 else if(S_ISLNK (mode)) typestr = "Symbolic Link";
777 else if(S_ISSOCK(mode)) typestr = "Socket";
779 typestr = "<unknown type>";
783 sprintf(modestr, "mode %06o: perm %c%c%c %c%c%c %c%c%c %c%c%c, type %s",
785 mode & S_ISUID ? 's':' ',
786 mode & S_ISGID ? 'g':' ',
787 mode & S_ISVTX ? 't':' ',
788 mode & S_IRUSR ? 'r':'-',
789 mode & S_IWUSR ? 'w':'-',
790 mode & S_IXUSR ? 'x':'-',
791 mode & S_IRGRP ? 'r':'-',
792 mode & S_IWGRP ? 'w':'-',
793 mode & S_IXGRP ? 'x':'-',
794 mode & S_IROTH ? 'r':'-',
795 mode & S_IWOTH ? 'w':'-',
796 mode & S_IXOTH ? 'x':'-',
809 char hans[HANDLE_STR];
811 if (dm_path_to_fshandle(fsname, fs_hanpp, fs_hlenp) == -1) {
812 errno_msg("Can't get filesystem handle");
816 hantoa(*fs_hanpp, *fs_hlenp, hans);
817 err_msg("File system handle for %s: %s\n", fsname, hans);
824 Set the event disposition for this filesystem to include all valid
825 DMAPI events so that we receive all events for this filesystem.
826 Also set DM_EVENT_MOUNT disposition for the global handle.
827 It does not make sense to specify DM_EVENT_USER in the disposition
828 mask since a session is always unconditionally registered for these
831 Returns non-zero on error.
840 dm_eventset_t eventlist;
843 err_msg("Setting event disposition to send all "
844 "events to this session\n");
847 /* DM_EVENT_MOUNT must be sent in a separate request using the global
848 handle. If we ever support more than one filesystem at a time, this
849 request should be moved out of this routine to a place where it is
853 DMEV_ZERO(eventlist);
854 DMEV_SET(DM_EVENT_MOUNT, eventlist);
856 if (dm_set_disp(sid, DM_GLOBAL_HANP, DM_GLOBAL_HLEN, DM_NO_TOKEN,
857 &eventlist, DM_EVENT_MAX) == -1) {
858 errno_msg("Can't set event disposition for mount");
862 DMEV_ZERO(eventlist);
864 /* File system administration events. */
866 DMEV_SET(DM_EVENT_PREUNMOUNT, eventlist);
867 DMEV_SET(DM_EVENT_UNMOUNT, eventlist);
868 DMEV_SET(DM_EVENT_NOSPACE, eventlist);
870 /* While DM_EVENT_DEBUT is optional, it appears that the spec always
871 lets it be specified in a dm_set_disp call; its just that the
872 event will never be seen on some platforms.
875 DMEV_SET(DM_EVENT_DEBUT, eventlist);
878 /* Namespace events. */
880 DMEV_SET(DM_EVENT_CREATE, eventlist);
881 DMEV_SET(DM_EVENT_POSTCREATE, eventlist);
882 DMEV_SET(DM_EVENT_REMOVE, eventlist);
883 DMEV_SET(DM_EVENT_POSTREMOVE, eventlist);
884 DMEV_SET(DM_EVENT_RENAME, eventlist);
885 DMEV_SET(DM_EVENT_POSTRENAME, eventlist);
886 DMEV_SET(DM_EVENT_LINK, eventlist);
887 DMEV_SET(DM_EVENT_POSTLINK, eventlist);
888 DMEV_SET(DM_EVENT_SYMLINK, eventlist);
889 DMEV_SET(DM_EVENT_POSTSYMLINK, eventlist);
891 /* Managed region data events. */
893 DMEV_SET(DM_EVENT_READ, eventlist);
894 DMEV_SET(DM_EVENT_WRITE, eventlist);
895 DMEV_SET(DM_EVENT_TRUNCATE, eventlist);
897 /* Metadata events. */
899 DMEV_SET(DM_EVENT_ATTRIBUTE, eventlist);
900 #if ! defined ( __sgi ) && ! defined ( VERITAS_21 ) && !defined(linux)
901 DMEV_SET(DM_EVENT_CANCEL, eventlist); /* not supported on SGI */
903 #if !defined( __sgi) && !defined(linux)
904 DMEV_SET(DM_EVENT_CLOSE, eventlist); /* not supported on SGI */
906 DMEV_SET(DM_EVENT_DESTROY, eventlist);
910 /* DM_EVENT_USER - always enabled - causes EINVAL if specified */
912 if (dm_set_disp(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
913 &eventlist, DM_EVENT_MAX) == -1) {
914 errno_msg("Can't set event disposition for filesystem");
922 Enable event generation on each valid filesystem-based DMAPI event
923 within the given file system.
925 Returns non-zero on errors.
934 dm_eventset_t eventlist;
937 err_msg("Setting event list to enable all events "
938 "for this file system\n");
940 DMEV_ZERO(eventlist);
942 /* File system administration events. */
944 /* DM_EVENT_MOUNT - always enabled on the global handle - causes
947 DMEV_SET(DM_EVENT_PREUNMOUNT, eventlist);
948 DMEV_SET(DM_EVENT_UNMOUNT, eventlist);
949 DMEV_SET(DM_EVENT_NOSPACE, eventlist);
950 /* DM_EVENT_DEBUT - always enabled - causes EINVAL if specified. */
952 /* Namespace events. */
954 DMEV_SET(DM_EVENT_CREATE, eventlist);
955 DMEV_SET(DM_EVENT_POSTCREATE, eventlist);
956 DMEV_SET(DM_EVENT_REMOVE, eventlist);
957 DMEV_SET(DM_EVENT_POSTREMOVE, eventlist);
958 DMEV_SET(DM_EVENT_RENAME, eventlist);
959 DMEV_SET(DM_EVENT_POSTRENAME, eventlist);
960 DMEV_SET(DM_EVENT_LINK, eventlist);
961 DMEV_SET(DM_EVENT_POSTLINK, eventlist);
962 DMEV_SET(DM_EVENT_SYMLINK, eventlist);
963 DMEV_SET(DM_EVENT_POSTSYMLINK, eventlist);
965 /* Managed region data events. These are not settable by
966 dm_set_eventlist on a filesystem basis. They are meant
967 to be set using dm_set_region on regular files only.
968 However, in the SGI implementation, they are filesystem-settable.
969 Since this is useful for testing purposes, do it.
974 /* DM_EVENT_TRUNCATE */
976 /* Metadata events. */
978 DMEV_SET(DM_EVENT_ATTRIBUTE, eventlist);
979 #if ! defined ( __sgi ) && ! defined ( VERITAS_21 ) && ! defined(linux)
980 DMEV_SET(DM_EVENT_CANCEL, eventlist); /* not supported on SGI */
982 #if !defined( __sgi) && !defined(linux)
983 DMEV_SET(DM_EVENT_CLOSE, eventlist); /* not supported on SGI */
985 DMEV_SET(DM_EVENT_DESTROY, eventlist);
989 /* DM_EVENT_USER - always enabled - causes EINVAL if specified */
991 if (dm_set_eventlist(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
992 &eventlist, DM_EVENT_MAX) == -1) {
993 errno_msg("Can't set event list");
1001 Disable monitoring for all events in the DMAPI for the given
1002 file system. This is done before exiting so that future
1003 operations won't hang waiting for their events to be handled.
1005 Returns non-zero on errors.
1014 dm_eventset_t eventlist;
1017 err_msg("Clearing event list to disable all events "
1018 "for this filesystem\n");
1020 DMEV_ZERO(eventlist);
1022 if (dm_set_eventlist(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
1023 &eventlist, DM_EVENT_MAX) == -1) {
1024 errno_msg("Can't clear event list");
1032 * Respond to any events which haven't been handled yet.
1033 * dm_getall_tokens provides a list of tokens for the outstanding events.
1034 * dm_find_eventmsg uses the token to lookup the corresponding message.
1035 * The message is passed to handle_message() for normal response processing.
1042 u_int nbytes, ntokens = 0, ret_ntokens, i;
1043 dm_token_t *tokenbuf = NULL;
1044 size_t buflen, ret_buflen;
1045 char *msgbuf = NULL;
1049 err_msg("Responding to any outstanding delivered event messages\n");
1052 * Initial sizes for the token and message buffers
1054 ret_buflen = 16 * (sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t)
1059 * The E2BIG dance...
1060 * Take a guess at how large to make the buffer, starting with ret_ntokens.
1061 * If the routine returns E2BIG, use the returned size and try again.
1062 * If we're already using the returned size, double it and try again.
1065 ntokens = (ntokens != ret_ntokens) ? ret_ntokens : ntokens*2;
1066 nbytes = ntokens * (sizeof(dm_token_t) + sizeof(dm_vardata_t));
1067 tokenbuf = malloc(nbytes);
1068 if (tokenbuf == NULL) {
1069 err_msg("Can't malloc %d bytes for tokenbuf\n", nbytes);
1073 error = dm_getall_tokens(sid, ntokens, tokenbuf, &ret_ntokens);
1074 } while (error && errno == E2BIG);
1077 errno_msg("Can't get all outstanding tokens");
1081 for (i = 0; i < ret_ntokens; i++) {
1083 err_msg("Responding to outstanding event for token %d\n",(int)*tokenbuf);
1086 * The E2BIG dance reprise...
1089 buflen = (buflen != ret_buflen) ? ret_buflen : buflen * 2;
1090 msgbuf = malloc(buflen);
1091 if (msgbuf == NULL) {
1092 err_msg("Can't malloc %d bytes for msgbuf\n", buflen);
1096 error = dm_find_eventmsg(sid, *tokenbuf, buflen, msgbuf, &ret_buflen);
1097 } while (error && errno == E2BIG);
1099 errno_msg("Can't find the event message for token %d", (int)*tokenbuf);
1103 msg = (dm_eventmsg_t *) msgbuf;
1104 while (msg != NULL) {
1105 error = handle_message(sid, msg);
1108 msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *);
1124 * Establish an exit handler since we run in an infinite loop
1127 establish_handler(void)
1129 struct sigaction act;
1132 * Set up signals so that we can wait for spawned children
1134 act.sa_handler = exit_handler;
1136 sigemptyset(&act.sa_mask);
1138 (void)sigaction(SIGHUP, &act, NULL);
1139 (void)sigaction(SIGINT, &act, NULL);
1140 (void)sigaction(SIGQUIT, &act, NULL);
1141 (void)sigaction(SIGTERM, &act, NULL);
1142 (void)sigaction(SIGUSR1, &act, NULL);
1143 (void)sigaction(SIGUSR1, &act, NULL);
1144 (void)sigaction(SIGUSR2, &act, NULL);
1153 * Stop events from being generated for the given file system
1154 * Respond to any events that were delivered but unanswered
1155 * (the event loop may have been in the middle of taking care of the event)
1156 * Try getting any undelivered events but don't block if none are there
1157 * (the file system may have generated an event after we killed dm_get_events)
1158 * Shutdown the session using the global "sid" variable.
1169 err_msg("Exiting...\n");
1171 error = get_fs_handle(fsname, &fs_hanp, &fs_hlen);
1174 error = clear_events(sid, fs_hanp, fs_hlen);
1176 /* just keep going */ ;
1179 error = finish_responding(sid);
1181 /* just keep going */ ;
1183 err_msg("Processing any undelivered event messages\n");
1184 event_loop(sid, 0 /*waitflag*/);
1186 err_msg("Shutting down the session\n");
1188 error = dm_destroy_session(sid);
1190 errno_msg("Can't shut down session - use 'mrmean -kv' to clean up!");