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"
41 #define VALLLD "\t%-15s %lld\n"
47 int main (int, char **);
48 static void event_loop (dm_sessid_t, int);
49 int handle_message (dm_sessid_t, dm_eventmsg_t *);
50 static int format_mode(mode_t mode, char **ptr);
51 static int get_fs_handle (char *, void **, size_t *);
52 static int set_disposition(dm_sessid_t, void *, size_t);
53 static int set_events (dm_sessid_t, void *, size_t);
54 static int clear_events (dm_sessid_t, void *, size_t);
55 int finish_responding(dm_sessid_t);
56 int establish_handler(void);
57 void exit_handler (int);
59 #define MAXNAMELEN 256
62 * Keep these global so the exit_handler and err_msg routines can get to them
68 dm_sessid_t oldsid = 0;
76 fprintf(stderr, "Usage: %s ", prog);
77 fprintf(stderr, " <-S oldsid> <-v verbose> ");
78 fprintf(stderr, "filesystem \n");
94 /* Progname = argv[0];*/ Progname = "print_event";
97 while ((c = getopt(argc, argv, "vs:S:")) != EOF) {
100 Sleep = atoi(optarg);
103 oldsid = atoi(optarg);
114 if (optind >= argc) {
118 fsname = argv[optind];
119 if (fsname == NULL) {
125 * Establish an exit handler
127 error = establish_handler();
132 * Init the dmapi, and get a filesystem handle so
133 * we can set up our events
139 error = setup_dmapi(&sid);
144 error = get_fs_handle(fsname, &fs_hanp, &fs_hlen);
149 * Set the event disposition so that our session will receive
150 * all the events for the given file system
152 error = set_disposition(sid, fs_hanp, fs_hlen);
157 * Enable monitoring for all events in the given file system
159 error = set_events(sid, fs_hanp, fs_hlen);
164 * Now sit in an infinite loop, reporting on any events that occur.
165 * The program is exited after a signal through exit_handler().
168 event_loop(sid, 1 /*waitflag*/);
171 * If we get here, cleanup after the event_loop failure
180 * Main event loop processing
182 * The waitflag argument is set to 1 when we call this from main().
183 * In this case, continuously process incoming events,
184 * blocking if there are none available.
185 * In the exit_handler(), call this routine with waitflag=0.
186 * Just try to read the events once in this case with no blocking.
201 * We take a swag at a buffer size. If it's wrong, we can
205 bufsize = sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + HANDLE_LEN;
207 msgbuf = (void *)malloc(bufsize);
208 if (msgbuf == NULL) {
209 err_msg("Can't allocate memory for buffer");
214 error = dm_get_events(sid, ALL_AVAIL_MSGS,
215 waitflag ? DM_EV_WAIT:0, bufsize, msgbuf, &bufsize);
217 if (errno == EAGAIN) {
222 if (errno == E2BIG) {
224 msgbuf = (void *)malloc(bufsize);
225 if (msgbuf == NULL) {
226 err_msg("Can't resize msg buffer");
231 errno_msg("Error getting events from DMAPI (%d)", errno);
236 * Walk through the message buffer, pull out each individual
237 * message, and dispatch the messages to handle_message(),
238 * which will respond to the events.
242 msg = (dm_eventmsg_t *)msgbuf;
243 while (msg != NULL ) {
245 error = handle_message(sid, msg);
250 msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *);
252 if (count != 1 && Verbose) {
253 err_msg("Found %d events in one call to "
254 "dm_get_events\n", count);
263 print_one_mount_event(
266 void *hanp1, *hanp2, *hanp3;
267 size_t hlen1, hlen2, hlen3;
268 char hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR];
271 char nams1[MAXNAMELEN], nams2[MAXNAMELEN];
275 dm_namesp_event_t *msg_ne = (dm_namesp_event_t *)msg;
278 msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
280 hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *);
281 hlen1 = DM_GET_LEN (msg_ne, ne_handle1);
282 hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *);
283 hlen2 = DM_GET_LEN (msg_ne, ne_handle2);
284 namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *);
285 nlen1 = DM_GET_LEN (msg_ne, ne_name1);
286 namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *);
287 nlen2 = DM_GET_LEN (msg_ne, ne_name2);
290 mode = msg_ne->ne_mode;
292 dm_mount_event_t *msg_me = (dm_mount_event_t *)msg;
294 hanp1 = DM_GET_VALUE(msg_me, me_handle1, void *);
295 hlen1 = DM_GET_LEN(msg_me, me_handle1);
296 hanp2 = DM_GET_VALUE(msg_me, me_handle2, void *);
297 hlen2 = DM_GET_LEN(msg_me, me_handle2);
298 namp1 = DM_GET_VALUE(msg_me, me_name1, void *);
299 nlen1 = DM_GET_LEN(msg_me, me_name1);
300 namp2 = DM_GET_VALUE(msg_me, me_name2, void *);
301 nlen2 = DM_GET_LEN(msg_me, me_name2);
302 hanp3 = DM_GET_VALUE(msg_me, me_roothandle, void *);
303 hlen3 = DM_GET_LEN(msg_me, me_roothandle);
304 mode = msg_me->me_mode;
305 #endif /* VERITAS_21 */
307 if (hanp1 && hlen1) {
308 hantoa(hanp1, hlen1, hans1);
310 sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
312 if (hanp2 && hlen2) {
313 hantoa(hanp2, hlen2, hans2);
315 sprintf(hans2, "<BAD HANDLE, hlen %d>", hlen2);
317 if (hanp3 && hlen3) {
318 hantoa(hanp3, hlen3, hans3);
320 sprintf(hans3, "<BAD HANDLE, hlen %d>", hlen3);
322 if (namp1 && nlen1) {
323 strncpy(nams1, namp1, nlen1);
324 if (nlen1 != sizeof(nams1))
327 sprintf(nams1, "<BAD STRING, nlen %d>", nlen1);
329 if (namp2 && nlen2) {
330 strncpy(nams2, namp2, nlen2);
331 if (nlen2 != sizeof(nams2))
334 sprintf(nams2, "<BAD STRING, nlen %d>", nlen2);
337 printf(VALS VALS VALS VALS VALS VALD,
339 "mtpt handle", hans2,
341 "media desig", nams2,
342 "root handle", hans3,
348 * First, weed out the events which return interesting structures.
349 * If it's not one of those, unpack the dm_namesp_event structure
350 * and display the contents.
359 dm_response_t response;
360 int respond, respcode;
361 dm_namesp_event_t *msg_ne;
363 dm_mount_event_t *msg_me;
365 void *hanp1, *hanp2, *namp1, *namp2;
366 u_int hlen1, hlen2, nlen1, nlen2;
367 char hans1[HANDLE_STR], hans2[HANDLE_STR];
368 char nams1[MAXNAMELEN], nams2[MAXNAMELEN];
371 * Set the defaults for responding to events
374 response = DM_RESP_CONTINUE;
377 /***** USER EVENTS *****/
379 if (msg->ev_type == DM_EVENT_USER) {
384 "user", msg->ev_token, msg->ev_sequence);
386 /* print private data as ascii or hex if it exists DM_CONFIG_MAX_MESSAGE_DATA */
388 privp = DM_GET_VALUE(msg, ev_data, char *);
389 plen = DM_GET_LEN (msg, ev_data);
391 for (i = 0; i < plen; i++) {
392 if (!isprint(privp[i]) && !isspace(privp[i]))
395 if (i == plen - 1 && privp[i] == '\0') {
399 printf("\t%-15s ", "privdata");
400 for (i = 0; i < plen; i++) {
401 printf("%.2x", privp[i]);
407 "privdata", "<NONE>");
410 if (msg->ev_token == DM_INVALID_TOKEN) /* async dm_send_msg event */
414 /***** CANCEL EVENT *****/
416 /* Not implemented on SGI or Veritas */
418 else if (msg->ev_type == DM_EVENT_CANCEL) {
419 dm_cancel_event_t *msg_ce;
421 msg_ce = DM_GET_VALUE(msg, ev_data, dm_cancel_event_t *);
422 printf(HDR VALD VALD,
423 "cancel", msg->ev_token, msg->ev_sequence,
424 "sequence", msg_ce->ce_sequence,
425 "token", msg_ce->ce_token);
429 /***** DATA EVENTS *****/
431 else if (msg->ev_type == DM_EVENT_READ ||
432 msg->ev_type == DM_EVENT_WRITE ||
433 msg->ev_type == DM_EVENT_TRUNCATE) {
434 dm_data_event_t *msg_de;
436 msg_de = DM_GET_VALUE(msg, ev_data, dm_data_event_t *);
437 hanp1 = DM_GET_VALUE(msg_de, de_handle, void *);
438 hlen1 = DM_GET_LEN (msg_de, de_handle);
439 if (hanp1 && hlen1) {
440 hantoa(hanp1, hlen1, hans1);
442 sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
445 switch(msg->ev_type) {
448 printf(HDR VALS VALLLD VALLLD,
449 "read", msg->ev_token, msg->ev_sequence,
450 "file handle", hans1,
451 "offset", msg_de->de_offset,
452 "length", msg_de->de_length);
456 printf(HDR VALS VALLLD VALLLD,
457 "write", msg->ev_token, msg->ev_sequence,
458 "file handle", hans1,
459 "offset", msg_de->de_offset,
460 "length", msg_de->de_length);
463 case DM_EVENT_TRUNCATE:
464 printf(HDR VALS VALLLD VALLLD,
465 "truncate", msg->ev_token, msg->ev_sequence,
466 "file handle", hans1,
467 "offset", msg_de->de_offset,
468 "length", msg_de->de_length);
474 /***** DESTROY EVENT *****/
476 else if (msg->ev_type == DM_EVENT_DESTROY) {
477 dm_destroy_event_t *msg_ds;
478 char attrname[DM_ATTR_NAME_SIZE + 1];
483 msg_ds= DM_GET_VALUE(msg, ev_data, dm_destroy_event_t *);
484 hanp1 = DM_GET_VALUE(msg_ds, ds_handle, void *);
485 hlen1 = DM_GET_LEN (msg_ds, ds_handle);
486 if (hanp1 && hlen1) {
487 hantoa(hanp1, hlen1, hans1);
489 sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
491 if (msg_ds->ds_attrname.an_chars[0] != '\0') {
492 strncpy(attrname, (char *)msg_ds->ds_attrname.an_chars, sizeof(attrname));
494 strcpy(attrname, "<NONE>");
496 printf(HDR VALS VALS,
497 "destroy", msg->ev_token, msg->ev_sequence,
499 "attrname", attrname);
500 copy = DM_GET_VALUE(msg_ds, ds_attrcopy, u_char *);
501 clen = DM_GET_LEN (msg_ds, ds_attrcopy);
503 printf("\t%-15s ", "attrcopy");
504 for (i = 0; i < clen; i++) {
505 printf("%.2x", copy[i]);
509 printf(VALS, "attrcopy", "<NONE>");
514 /***** MOUNT EVENT *****/
516 else if (msg->ev_type == DM_EVENT_MOUNT) {
517 printf(HDR, "mount", msg->ev_token, msg->ev_sequence);
519 msg_me = DM_GET_VALUE(msg, ev_data, dm_mount_event_t *);
520 print_one_mount_event(msg_me);
521 #else /* VERITAS_21 */
522 msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
523 print_one_mount_event(msg_ne);
524 #endif /* VERITAS_21 */
527 /***** NAMESPACE EVENTS *****/
532 msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
533 hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *);
534 hlen1 = DM_GET_LEN (msg_ne, ne_handle1);
535 hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *);
536 hlen2 = DM_GET_LEN (msg_ne, ne_handle2);
537 namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *);
538 nlen1 = DM_GET_LEN (msg_ne, ne_name1);
539 namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *);
540 nlen2 = DM_GET_LEN (msg_ne, ne_name2);
542 if (hanp1 && hlen1) {
543 hantoa(hanp1, hlen1, hans1);
545 if (hanp2 && hlen2) {
546 hantoa(hanp2, hlen2, hans2);
548 if (namp1 && nlen1) {
549 strncpy(nams1, namp1, nlen1);
550 if (nlen1 != sizeof(nams1))
553 if (namp2 && nlen2) {
554 strncpy(nams2, namp2, nlen2);
555 if (nlen2 != sizeof(nams2))
559 if (msg->ev_type == DM_EVENT_PREUNMOUNT ||
560 msg->ev_type == DM_EVENT_UNMOUNT) {
561 if (msg_ne->ne_mode == 0) {
564 } else if (msg_ne->ne_mode == DM_UNMOUNT_FORCE) {
566 } else if (msg_ne->ne_mode > 0) {
573 } else if (msg->ev_type == DM_EVENT_CREATE ||
574 msg->ev_type == DM_EVENT_POSTCREATE ||
575 msg->ev_type == DM_EVENT_REMOVE ||
576 msg->ev_type == DM_EVENT_POSTREMOVE) {
577 if (format_mode(msg_ne->ne_mode, &type)) {
582 switch(msg->ev_type) {
584 case DM_EVENT_PREUNMOUNT:
585 printf(HDR VALS VALS VALS,
586 "preunmount", msg->ev_token, msg->ev_sequence,
589 "unmount mode", type);
592 case DM_EVENT_UNMOUNT:
593 printf(HDR VALS VALS VALD,
594 "unmount", msg->ev_token, msg->ev_sequence,
596 "unmount mode", type,
597 "retcode", msg_ne->ne_retcode);
600 case DM_EVENT_NOSPACE:
602 "nospace", msg->ev_token, msg->ev_sequence,
604 response = DM_RESP_ABORT;
608 case DM_EVENT_DEBUT: /* not supported on SGI */
610 "debut", msg->ev_token, msg->ev_sequence,
614 case DM_EVENT_CREATE:
615 printf(HDR VALS VALS VALS,
616 "create", msg->ev_token, msg->ev_sequence,
622 case DM_EVENT_POSTCREATE:
623 printf(HDR VALS VALS VALS VALS VALD,
624 "postcreate", msg->ev_token, msg->ev_sequence,
629 "retcode", msg_ne->ne_retcode);
633 case DM_EVENT_REMOVE:
634 printf(HDR VALS VALS VALS,
635 "remove", msg->ev_token, msg->ev_sequence,
641 case DM_EVENT_POSTREMOVE:
642 printf(HDR VALS VALS VALS VALD,
643 "postremove", msg->ev_token, msg->ev_sequence,
647 "retcode", msg_ne->ne_retcode);
651 case DM_EVENT_RENAME:
652 printf(HDR VALS VALS VALS VALS,
653 "rename", msg->ev_token, msg->ev_sequence,
660 case DM_EVENT_POSTRENAME:
661 printf(HDR VALS VALS VALS VALS VALD,
662 "postrename", msg->ev_token, msg->ev_sequence,
667 "retcode", msg_ne->ne_retcode);
671 case DM_EVENT_SYMLINK:
672 printf(HDR VALS VALS VALS,
673 "symlink", msg->ev_token, msg->ev_sequence,
679 case DM_EVENT_POSTSYMLINK:
680 printf(HDR VALS VALS VALS VALS VALD,
681 "postsymlink", msg->ev_token, msg->ev_sequence,
686 "retcode", msg_ne->ne_retcode);
691 printf(HDR VALS VALS VALS,
692 "link", msg->ev_token, msg->ev_sequence,
698 case DM_EVENT_POSTLINK:
699 printf(HDR VALS VALS VALS VALD,
700 "postlink", msg->ev_token, msg->ev_sequence,
704 "retcode", msg_ne->ne_retcode);
708 case DM_EVENT_ATTRIBUTE:
710 "attribute", msg->ev_token, msg->ev_sequence,
715 case DM_EVENT_CLOSE: /* not supported on SGI */
717 "close", msg->ev_token, msg->ev_sequence,
725 "<UNKNOWN>", msg->ev_token, msg->ev_sequence,
726 "ev_type", msg->ev_type);
727 if (msg->ev_token == DM_INVALID_TOKEN)
734 * Now respond to those messages which require a response
737 error = dm_respond_event(sid, msg->ev_token, response, respcode, 0, 0);
739 errno_msg("Can't respond to event");
743 err_msg("Sleeping for %d seconds!\n", Sleep);
753 Convert a mode_t field into a printable string.
755 Returns non-zero if the mode_t is invalid. The string is
756 returned in *ptr, whether there is an error or not.
764 static char modestr[100];
768 if (S_ISFIFO(mode)) typestr = "FIFO";
769 else if(S_ISCHR (mode)) typestr = "Character Device";
770 else if(S_ISBLK (mode)) typestr = "Block Device";
771 else if(S_ISDIR (mode)) typestr = "Directory";
772 else if(S_ISREG (mode)) typestr = "Regular File";
773 else if(S_ISLNK (mode)) typestr = "Symbolic Link";
774 else if(S_ISSOCK(mode)) typestr = "Socket";
776 typestr = "<unknown type>";
780 sprintf(modestr, "mode %06o: perm %c%c%c %c%c%c %c%c%c %c%c%c, type %s",
782 mode & S_ISUID ? 's':' ',
783 mode & S_ISGID ? 'g':' ',
784 mode & S_ISVTX ? 't':' ',
785 mode & S_IRUSR ? 'r':'-',
786 mode & S_IWUSR ? 'w':'-',
787 mode & S_IXUSR ? 'x':'-',
788 mode & S_IRGRP ? 'r':'-',
789 mode & S_IWGRP ? 'w':'-',
790 mode & S_IXGRP ? 'x':'-',
791 mode & S_IROTH ? 'r':'-',
792 mode & S_IWOTH ? 'w':'-',
793 mode & S_IXOTH ? 'x':'-',
806 char hans[HANDLE_STR];
808 if (dm_path_to_fshandle(fsname, fs_hanpp, fs_hlenp) == -1) {
809 errno_msg("Can't get filesystem handle");
813 hantoa(*fs_hanpp, *fs_hlenp, hans);
814 err_msg("File system handle for %s: %s\n", fsname, hans);
821 Set the event disposition for this filesystem to include all valid
822 DMAPI events so that we receive all events for this filesystem.
823 Also set DM_EVENT_MOUNT disposition for the global handle.
824 It does not make sense to specify DM_EVENT_USER in the disposition
825 mask since a session is always unconditionally registered for these
828 Returns non-zero on error.
837 dm_eventset_t eventlist;
840 err_msg("Setting event disposition to send all "
841 "events to this session\n");
844 /* DM_EVENT_MOUNT must be sent in a separate request using the global
845 handle. If we ever support more than one filesystem at a time, this
846 request should be moved out of this routine to a place where it is
850 DMEV_ZERO(eventlist);
851 DMEV_SET(DM_EVENT_MOUNT, eventlist);
853 if (dm_set_disp(sid, DM_GLOBAL_HANP, DM_GLOBAL_HLEN, DM_NO_TOKEN,
854 &eventlist, DM_EVENT_MAX) == -1) {
855 errno_msg("Can't set event disposition for mount");
859 DMEV_ZERO(eventlist);
861 /* File system administration events. */
863 DMEV_SET(DM_EVENT_PREUNMOUNT, eventlist);
864 DMEV_SET(DM_EVENT_UNMOUNT, eventlist);
865 DMEV_SET(DM_EVENT_NOSPACE, eventlist);
867 /* While DM_EVENT_DEBUT is optional, it appears that the spec always
868 lets it be specified in a dm_set_disp call; its just that the
869 event will never be seen on some platforms.
872 DMEV_SET(DM_EVENT_DEBUT, eventlist);
875 /* Namespace events. */
877 DMEV_SET(DM_EVENT_CREATE, eventlist);
878 DMEV_SET(DM_EVENT_POSTCREATE, eventlist);
879 DMEV_SET(DM_EVENT_REMOVE, eventlist);
880 DMEV_SET(DM_EVENT_POSTREMOVE, eventlist);
881 DMEV_SET(DM_EVENT_RENAME, eventlist);
882 DMEV_SET(DM_EVENT_POSTRENAME, eventlist);
883 DMEV_SET(DM_EVENT_LINK, eventlist);
884 DMEV_SET(DM_EVENT_POSTLINK, eventlist);
885 DMEV_SET(DM_EVENT_SYMLINK, eventlist);
886 DMEV_SET(DM_EVENT_POSTSYMLINK, eventlist);
888 /* Managed region data events. */
890 DMEV_SET(DM_EVENT_READ, eventlist);
891 DMEV_SET(DM_EVENT_WRITE, eventlist);
892 DMEV_SET(DM_EVENT_TRUNCATE, eventlist);
894 /* Metadata events. */
896 DMEV_SET(DM_EVENT_ATTRIBUTE, eventlist);
897 #if ! defined ( __sgi ) && ! defined ( VERITAS_21 ) && !defined(linux)
898 DMEV_SET(DM_EVENT_CANCEL, eventlist); /* not supported on SGI */
900 #if !defined( __sgi) && !defined(linux)
901 DMEV_SET(DM_EVENT_CLOSE, eventlist); /* not supported on SGI */
903 DMEV_SET(DM_EVENT_DESTROY, eventlist);
907 /* DM_EVENT_USER - always enabled - causes EINVAL if specified */
909 if (dm_set_disp(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
910 &eventlist, DM_EVENT_MAX) == -1) {
911 errno_msg("Can't set event disposition for filesystem");
919 Enable event generation on each valid filesystem-based DMAPI event
920 within the given file system.
922 Returns non-zero on errors.
931 dm_eventset_t eventlist;
934 err_msg("Setting event list to enable all events "
935 "for this file system\n");
937 DMEV_ZERO(eventlist);
939 /* File system administration events. */
941 /* DM_EVENT_MOUNT - always enabled on the global handle - causes
944 DMEV_SET(DM_EVENT_PREUNMOUNT, eventlist);
945 DMEV_SET(DM_EVENT_UNMOUNT, eventlist);
946 DMEV_SET(DM_EVENT_NOSPACE, eventlist);
947 /* DM_EVENT_DEBUT - always enabled - causes EINVAL if specified. */
949 /* Namespace events. */
951 DMEV_SET(DM_EVENT_CREATE, eventlist);
952 DMEV_SET(DM_EVENT_POSTCREATE, eventlist);
953 DMEV_SET(DM_EVENT_REMOVE, eventlist);
954 DMEV_SET(DM_EVENT_POSTREMOVE, eventlist);
955 DMEV_SET(DM_EVENT_RENAME, eventlist);
956 DMEV_SET(DM_EVENT_POSTRENAME, eventlist);
957 DMEV_SET(DM_EVENT_LINK, eventlist);
958 DMEV_SET(DM_EVENT_POSTLINK, eventlist);
959 DMEV_SET(DM_EVENT_SYMLINK, eventlist);
960 DMEV_SET(DM_EVENT_POSTSYMLINK, eventlist);
962 /* Managed region data events. These are not settable by
963 dm_set_eventlist on a filesystem basis. They are meant
964 to be set using dm_set_region on regular files only.
965 However, in the SGI implementation, they are filesystem-settable.
966 Since this is useful for testing purposes, do it.
971 /* DM_EVENT_TRUNCATE */
973 /* Metadata events. */
975 DMEV_SET(DM_EVENT_ATTRIBUTE, eventlist);
976 #if ! defined ( __sgi ) && ! defined ( VERITAS_21 ) && ! defined(linux)
977 DMEV_SET(DM_EVENT_CANCEL, eventlist); /* not supported on SGI */
979 #if !defined( __sgi) && !defined(linux)
980 DMEV_SET(DM_EVENT_CLOSE, eventlist); /* not supported on SGI */
982 DMEV_SET(DM_EVENT_DESTROY, eventlist);
986 /* DM_EVENT_USER - always enabled - causes EINVAL if specified */
988 if (dm_set_eventlist(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
989 &eventlist, DM_EVENT_MAX) == -1) {
990 errno_msg("Can't set event list");
998 Disable monitoring for all events in the DMAPI for the given
999 file system. This is done before exiting so that future
1000 operations won't hang waiting for their events to be handled.
1002 Returns non-zero on errors.
1011 dm_eventset_t eventlist;
1014 err_msg("Clearing event list to disable all events "
1015 "for this filesystem\n");
1017 DMEV_ZERO(eventlist);
1019 if (dm_set_eventlist(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
1020 &eventlist, DM_EVENT_MAX) == -1) {
1021 errno_msg("Can't clear event list");
1029 * Respond to any events which haven't been handled yet.
1030 * dm_getall_tokens provides a list of tokens for the outstanding events.
1031 * dm_find_eventmsg uses the token to lookup the corresponding message.
1032 * The message is passed to handle_message() for normal response processing.
1039 u_int nbytes, ntokens = 0, ret_ntokens, i;
1040 dm_token_t *tokenbuf = NULL;
1041 size_t buflen, ret_buflen;
1042 char *msgbuf = NULL;
1046 err_msg("Responding to any outstanding delivered event messages\n");
1049 * Initial sizes for the token and message buffers
1051 ret_buflen = 16 * (sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t)
1056 * The E2BIG dance...
1057 * Take a guess at how large to make the buffer, starting with ret_ntokens.
1058 * If the routine returns E2BIG, use the returned size and try again.
1059 * If we're already using the returned size, double it and try again.
1062 ntokens = (ntokens != ret_ntokens) ? ret_ntokens : ntokens*2;
1063 nbytes = ntokens * (sizeof(dm_token_t) + sizeof(dm_vardata_t));
1064 tokenbuf = malloc(nbytes);
1065 if (tokenbuf == NULL) {
1066 err_msg("Can't malloc %d bytes for tokenbuf\n", nbytes);
1070 error = dm_getall_tokens(sid, ntokens, tokenbuf, &ret_ntokens);
1071 } while (error && errno == E2BIG);
1074 errno_msg("Can't get all outstanding tokens");
1078 for (i = 0; i < ret_ntokens; i++) {
1080 err_msg("Responding to outstanding event for token %d\n",(int)*tokenbuf);
1083 * The E2BIG dance reprise...
1086 buflen = (buflen != ret_buflen) ? ret_buflen : buflen * 2;
1087 msgbuf = malloc(buflen);
1088 if (msgbuf == NULL) {
1089 err_msg("Can't malloc %d bytes for msgbuf\n", buflen);
1093 error = dm_find_eventmsg(sid, *tokenbuf, buflen, msgbuf, &ret_buflen);
1094 } while (error && errno == E2BIG);
1096 errno_msg("Can't find the event message for token %d", (int)*tokenbuf);
1100 msg = (dm_eventmsg_t *) msgbuf;
1101 while (msg != NULL) {
1102 error = handle_message(sid, msg);
1105 msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *);
1121 * Establish an exit handler since we run in an infinite loop
1124 establish_handler(void)
1126 struct sigaction act;
1129 * Set up signals so that we can wait for spawned children
1131 act.sa_handler = exit_handler;
1133 sigemptyset(&act.sa_mask);
1135 (void)sigaction(SIGHUP, &act, NULL);
1136 (void)sigaction(SIGINT, &act, NULL);
1137 (void)sigaction(SIGQUIT, &act, NULL);
1138 (void)sigaction(SIGTERM, &act, NULL);
1139 (void)sigaction(SIGUSR1, &act, NULL);
1140 (void)sigaction(SIGUSR1, &act, NULL);
1141 (void)sigaction(SIGUSR2, &act, NULL);
1150 * Stop events from being generated for the given file system
1151 * Respond to any events that were delivered but unanswered
1152 * (the event loop may have been in the middle of taking care of the event)
1153 * Try getting any undelivered events but don't block if none are there
1154 * (the file system may have generated an event after we killed dm_get_events)
1155 * Shutdown the session using the global "sid" variable.
1166 err_msg("Exiting...\n");
1168 error = get_fs_handle(fsname, &fs_hanp, &fs_hlen);
1171 error = clear_events(sid, fs_hanp, fs_hlen);
1173 /* just keep going */ ;
1176 error = finish_responding(sid);
1178 /* just keep going */ ;
1180 err_msg("Processing any undelivered event messages\n");
1181 event_loop(sid, 0 /*waitflag*/);
1183 err_msg("Shutting down the session\n");
1185 error = dm_destroy_session(sid);
1187 errno_msg("Can't shut down session - use 'mrmean -kv' to clean up!");