Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
monitor.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, 2013, 2014, 2015 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <glib.h>
23 #include <pthread.h>
24 #include <inttypes.h>
25 #include <glib.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include <assert.h>
29 
30 #include "log.h"
31 #include "alist.h"
32 #include "waitpipe.h"
33 #include "evloop.h"
34 
35 #include "monitor.h"
36 
37 static int init_done = 0;
38 
39 /*
40  * Our primary mutex: used for library initialization, serialized access
41  * to per-monitor locks;
42  */
43 static pthread_mutex_t monitor_mutex = PTHREAD_MUTEX_INITIALIZER;
44 
45 /*
46  * Objtypes have a per-type operations struct.
47  */
48 static GHashTable *objtype_ops_tab = NULL;
49 /*
50  * Sometimes objtypes have a global per-type mutex they want locked when
51  * they lookup an object; this table stores that. It is populated at
52  * objtype registration.
53  */
54 static GHashTable *objtype_mutex_tab = NULL;
55 /*
56  * Sometimes we quickly want to list all objects of a type, or do
57  * something with them.
58  */
59 static GHashTable *objtype_objid_obj_tab;
60 /*
61  * Each object might have some state associated with it; store it.
62  */
63 static GHashTable *objtype_objid_objstate_tab;
64 
65 /*
66  * This is a global counter for generating unique objids. Object ids
67  * must be globally unique so that objtypes can exist within the same
68  * "namespace".
69  */
70 static int monitor_objid_idx = 0;
71 
72 /*
73  * Map of thread IDs to monitors.
74  */
75 static GHashTable *tid_monitor_tab = NULL;
76 /*
77  * Maps of objs/objids to monitors, objtypes, and objid/obj.
78  *
79  * Each monitor has one primary object associated with it that it
80  * monitors, but it may have secondary objects as well. This table
81  * holds them (as well as the primary obj info).
82  *
83  * Sometimes we want to lookup by obj, sometimes by objid. So the
84  * multiplicity of hashtables is just for convenience.
85  */
86 static GHashTable *obj_monitor_tab = NULL;
87 static GHashTable *objid_monitor_tab = NULL;
88 static GHashTable *obj_objtype_tab;
89 static GHashTable *objid_objtype_tab;
90 static GHashTable *obj_objid_tab;
91 static GHashTable *objid_obj_tab;
92 
93 void monitor_init(void) {
94  if (init_done)
95  return;
96 
97  pthread_mutex_lock(&monitor_mutex);
98 
99  if (init_done) {
100  pthread_mutex_unlock(&monitor_mutex);
101  return;
102  }
103 
104  objtype_ops_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
105  objtype_mutex_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
106  objtype_objid_obj_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
107  objtype_objid_objstate_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
108 
109  tid_monitor_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
110 
111  obj_monitor_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
112  objid_monitor_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
113 
114  obj_objtype_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
115  objid_objtype_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
116 
117  obj_objid_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
118  objid_obj_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
119 
120  init_done = 1;
121 
122  pthread_mutex_unlock(&monitor_mutex);
123 
124  return;
125 }
126 
127 void monitor_fini(void) {
128  if (!init_done)
129  return;
130 
131  pthread_mutex_lock(&monitor_mutex);
132 
133  if (!init_done) {
134  pthread_mutex_unlock(&monitor_mutex);
135  return;
136  }
137 
138  g_hash_table_destroy(tid_monitor_tab);
139 
140  g_hash_table_destroy(obj_monitor_tab);
141  g_hash_table_destroy(objid_monitor_tab);
142 
143  g_hash_table_destroy(obj_objtype_tab);
144  g_hash_table_destroy(objid_objtype_tab);
145 
146  g_hash_table_destroy(obj_objid_tab);
147  g_hash_table_destroy(objid_obj_tab);
148 
149  g_hash_table_destroy(objtype_objid_objstate_tab);
150  g_hash_table_destroy(objtype_objid_obj_tab);
151  g_hash_table_destroy(objtype_ops_tab);
152  g_hash_table_destroy(objtype_mutex_tab);
153 
154  init_done = 0;
155 
156  pthread_mutex_unlock(&monitor_mutex);
157 
158  return;
159 }
160 
162  int retval;
163 
164  pthread_mutex_lock(&monitor_mutex);
165  retval = ++monitor_objid_idx;
166  while (g_hash_table_lookup(objid_monitor_tab,(gpointer)(uintptr_t)retval))
167  ++monitor_objid_idx;
168  pthread_mutex_unlock(&monitor_mutex);
169 
170  return retval;
171 }
172 
173 static struct monitor_objtype_ops *__monitor_lookup_objtype_ops(int objtype) {
174  struct monitor_objtype_ops *retval;
175 
176  retval = g_hash_table_lookup(objtype_ops_tab,(gpointer)(uintptr_t)objtype);
177 
178  return retval;
179 }
180 
181 static struct monitor_objtype_ops *monitor_lookup_objtype_ops(int objtype) {
182  struct monitor_objtype_ops *retval;
183 
184  pthread_mutex_lock(&monitor_mutex);
185  retval = __monitor_lookup_objtype_ops(objtype);
186  pthread_mutex_unlock(&monitor_mutex);
187 
188  return retval;
189 }
190 
191 static int __monitor_lookup_objid(int objid,
192  int *objtype,void **obj,
193  struct monitor **monitor) {
194  struct monitor *_monitor;
195  int _objtype;
196  void *_obj;
197 
198  _monitor = g_hash_table_lookup(objid_monitor_tab,
199  (gpointer)(uintptr_t)objid);
200  if (!_monitor)
201  return 0;
202  _objtype = (int)(uintptr_t)g_hash_table_lookup(objid_objtype_tab,
203  (gpointer)(uintptr_t)objid);
204  if (!_objtype)
205  vwarn("bad objtype %d for obj %p monitor %p!\n",_objtype,obj,_monitor);
206  _obj = g_hash_table_lookup(objid_obj_tab,
207  (gpointer)(uintptr_t)objid);
208 
209  if (monitor)
210  *monitor = _monitor;
211  if (objtype)
212  *objtype = _objtype;
213  if (obj)
214  *obj = _obj;
215 
216  return 1;
217 }
218 
219 int monitor_lookup_objid(int objid,
220  int *objtype,void **obj,
221  struct monitor **monitor) {
222  int retval;
223 
224  pthread_mutex_lock(&monitor_mutex);
225  retval = __monitor_lookup_objid(objid,objtype,obj,monitor);
226  pthread_mutex_unlock(&monitor_mutex);
227 
228  return retval;
229 }
230 
231 int __monitor_lock_objtype(int objtype) {
232  pthread_mutex_t *mutex;
233 
234  mutex = (pthread_mutex_t *)g_hash_table_lookup(objtype_mutex_tab,
235  (gpointer)(uintptr_t)objtype);
236  if (!mutex)
237  return -1;
238 
239  pthread_mutex_lock(mutex);
240  return 0;
241 }
242 
243 int monitor_lock_objtype(int objtype) {
244  int rc;
245 
246  pthread_mutex_lock(&monitor_mutex);
247  rc = __monitor_lock_objtype(objtype);
248  pthread_mutex_unlock(&monitor_mutex);
249 
250  return rc;
251 }
252 
253 int __monitor_unlock_objtype(int objtype) {
254  pthread_mutex_t *mutex;
255 
256  mutex = (pthread_mutex_t *)g_hash_table_lookup(objtype_mutex_tab,
257  (gpointer)(uintptr_t)objtype);
258  if (!mutex)
259  return -1;
260 
261  pthread_mutex_unlock(mutex);
262  return 0;
263 }
264 
265 int monitor_unlock_objtype(int objtype) {
266  int rc;
267 
268  pthread_mutex_lock(&monitor_mutex);
269  rc = __monitor_unlock_objtype(objtype);
270  pthread_mutex_unlock(&monitor_mutex);
271 
272  return rc;
273 }
274 
276  return __monitor_unlock_objtype(objtype);
277 }
278 
280  int include_null) {
281  struct array_list *retval;
282  GHashTable *tmp_objid_obj_tab;
283  GHashTableIter iter;
284  void *obj;
285  int rc;
286  gpointer objid;
287 
288  pthread_mutex_lock(&monitor_mutex);
289 
290  rc = __monitor_lock_objtype(objtype);
291  if (rc) {
292  pthread_mutex_unlock(&monitor_mutex);
293  return NULL;
294  }
295  tmp_objid_obj_tab = (GHashTable *) \
296  g_hash_table_lookup(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype);
297  if (!tmp_objid_obj_tab) {
298  pthread_mutex_unlock(&monitor_mutex);
299  return NULL;
300  }
301 
302  retval = array_list_create(g_hash_table_size(tmp_objid_obj_tab));
303  g_hash_table_iter_init(&iter,tmp_objid_obj_tab);
304  while (g_hash_table_iter_next(&iter,&objid,&obj)) {
305  if (!include_null && !obj)
306  continue;
307  array_list_append(retval,objid);
308  }
309 
310  pthread_mutex_unlock(&monitor_mutex);
311 
312  return retval;
313 }
314 
316  int include_null) {
317  struct array_list *retval;
318  GHashTable *tmp_objid_obj_tab;
319  GHashTableIter iter;
320  void *obj;
321  int rc;
322 
323  pthread_mutex_lock(&monitor_mutex);
324 
325  rc = __monitor_lock_objtype(objtype);
326  if (rc) {
327  pthread_mutex_unlock(&monitor_mutex);
328  return NULL;
329  }
330  tmp_objid_obj_tab = (GHashTable *) \
331  g_hash_table_lookup(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype);
332  if (!tmp_objid_obj_tab) {
333  pthread_mutex_unlock(&monitor_mutex);
334  return NULL;
335  }
336 
337  retval = array_list_create(g_hash_table_size(tmp_objid_obj_tab));
338  g_hash_table_iter_init(&iter,tmp_objid_obj_tab);
339  while (g_hash_table_iter_next(&iter,NULL,&obj)) {
340  if (!include_null && !obj)
341  continue;
342  array_list_append(retval,obj);
343  }
344 
345  pthread_mutex_unlock(&monitor_mutex);
346 
347  return retval;
348 }
349 
350 int monitor_lookup_objid_lock_objtype(int objid,int objtype,
351  void **obj,struct monitor **monitor) {
352  int retval;
353 
354  pthread_mutex_lock(&monitor_mutex);
355  retval = __monitor_lock_objtype(objtype);
356  if (retval) {
357  verror("could not find objtype %d -- BUG!\n",objtype);
358  pthread_mutex_unlock(&monitor_mutex);
359  return 0;
360  }
361  retval = __monitor_lookup_objid(objid,NULL,obj,monitor);
362  if (!retval) {
363  vwarnopt(9,LA_LIB,LF_MONITOR,"could not find objid %d\n",objid);
364  __monitor_unlock_objtype(objtype);
365  }
366 
367  pthread_mutex_unlock(&monitor_mutex);
368 
369  return retval;
370 }
371 
373  void **obj,
374  struct monitor **monitor) {
375  int retval;
376  struct monitor *_monitor;
377 
378  pthread_mutex_lock(&monitor_mutex);
379  retval = __monitor_lock_objtype(objtype);
380  if (retval) {
381  verror("could not find objtype %d -- BUG!\n",objtype);
382  pthread_mutex_unlock(&monitor_mutex);
383  return 0;
384  }
385  retval = __monitor_lookup_objid(objid,NULL,obj,&_monitor);
386  if (retval && monitor)
387  *monitor = _monitor;
388  if (retval && _monitor)
389  pthread_mutex_lock(&_monitor->mutex);
390  if (!retval) {
391  vwarnopt(9,LA_LIB,LF_MONITOR,"could not find objid %d\n",objid);
392  __monitor_unlock_objtype(objtype);
393  }
394 
395  pthread_mutex_unlock(&monitor_mutex);
396 
397  return retval;
398 }
399 
401  int *objtype,void **obj,
402  struct monitor **monitor) {
403  int retval;
404  struct monitor *_monitor;
405 
406  pthread_mutex_lock(&monitor_mutex);
407  retval = __monitor_lookup_objid(objid,objtype,obj,&_monitor);
408  if (retval && monitor)
409  *monitor = _monitor;
410  if (retval && _monitor)
411  pthread_mutex_lock(&_monitor->mutex);
412  pthread_mutex_unlock(&monitor_mutex);
413 
414  return retval;
415 }
416 
417 static int __monitor_lookup_obj(void *obj,
418  int *objtype,int *objid,
419  struct monitor **monitor) {
420  struct monitor *_monitor;
421  int _objtype;
422  int _objid;
423 
424  _monitor = g_hash_table_lookup(obj_monitor_tab,obj);
425  if (!_monitor)
426  return 0;
427  _objtype = (int)(uintptr_t)g_hash_table_lookup(obj_objtype_tab,obj);
428  if (!_objtype)
429  vwarn("bad objtype %d for obj %p monitor %p!\n",_objtype,obj,_monitor);
430  _objid = (int)(uintptr_t)g_hash_table_lookup(obj_objid_tab,obj);
431  if (!_objid)
432  vwarn("bad objid %d for obj %p monitor %p!\n",_objid,obj,_monitor);
433 
434  if (monitor)
435  *monitor = _monitor;
436  if (objtype)
437  *objtype = _objtype;
438  if (objid)
439  *objid = _objid;
440 
441  return 1;
442 }
443 
444 int monitor_lookup_obj(void *obj,
445  int *objtype,int *objid,
446  struct monitor **monitor) {
447  int retval;
448 
449  pthread_mutex_lock(&monitor_mutex);
450  retval = __monitor_lookup_obj(obj,objtype,objid,monitor);
451  pthread_mutex_unlock(&monitor_mutex);
452 
453  return retval;
454 }
455 
457  int *objtype,int *objid,
458  struct monitor **monitor) {
459  int retval;
460  struct monitor *_monitor;
461 
462  pthread_mutex_lock(&monitor_mutex);
463  retval = __monitor_lookup_obj(obj,objtype,objid,&_monitor);
464  if (retval && monitor)
465  *monitor = _monitor;
466  if (retval && _monitor)
467  pthread_mutex_lock(&_monitor->mutex);
468  pthread_mutex_unlock(&monitor_mutex);
469 
470  return retval;
471 }
472 
473 
474 static int __monitor_add_obj(struct monitor *monitor,
475  int objid,int objtype,void *obj,void *objstate) {
476  int retval = -1;
477  struct monitor_objtype_ops *ops;
478  int _objtype = 0;
479  int _objid = 0;
480  void *_obj = NULL;
481  struct monitor *_monitor = NULL;
482  GHashTable *tmp_tab;
483 
484  if (!(ops = __monitor_lookup_objtype_ops(objtype))) {
485  verror("unknown objtype %d!\n",objtype);
486  errno = EINVAL;
487  goto out;
488  }
489 
490  if (__monitor_lookup_objid(objid,&_objtype,&_obj,&_monitor)) {
491  verror("obj %d (%p) already being monitored!\n",objid,_obj);
492  errno = EBUSY;
493  goto out;
494  }
495 
496  if (obj && __monitor_lookup_obj(obj,&_objtype,&_objid,&_monitor)) {
497  verror("obj %d (%p) already being monitored!\n",_objid,obj);
498  errno = EBUSY;
499  goto out;
500  }
501 
502  /*
503  * Insert it into all the hashtables.
504  */
505  g_hash_table_insert(obj_monitor_tab,obj,monitor);
506  g_hash_table_insert(objid_monitor_tab,(gpointer)(uintptr_t)objid,monitor);
507 
508  g_hash_table_insert(obj_objtype_tab,obj,(gpointer)(uintptr_t)objtype);
509  g_hash_table_insert(objid_objtype_tab,(gpointer)(uintptr_t)objid,
510  (gpointer)(uintptr_t)objtype);
511 
512  g_hash_table_insert(objid_obj_tab,(gpointer)(uintptr_t)objid,obj);
513  g_hash_table_insert(obj_objid_tab,obj,(gpointer)(uintptr_t)objid);
514 
515  if (ops->evloop_is_attached
516  && ops->evloop_is_attached(monitor->evloop,obj) > 0)
517  /* Skip attach; already attached. */
518  ;
519  else if (ops->evloop_attach) {
520  if (ops->evloop_attach(monitor->evloop,obj) < 0) {
521  verror("could not attach evloop to objid %d (%p)!\n",objid,obj);
522 
523  g_hash_table_remove(obj_monitor_tab,obj);
524  g_hash_table_remove(objid_monitor_tab,(gpointer)(uintptr_t)objid);
525 
526  g_hash_table_remove(obj_objtype_tab,obj);
527  g_hash_table_remove(objid_objtype_tab,(gpointer)(uintptr_t)objid);
528 
529  g_hash_table_remove(objid_obj_tab,(gpointer)(uintptr_t)objid);
530  g_hash_table_remove(obj_objid_tab,obj);
531 
532  goto out;
533  }
534  }
535 
536  tmp_tab = (GHashTable *) \
537  g_hash_table_lookup(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype);
538  g_hash_table_insert(tmp_tab,(gpointer)(uintptr_t)objid,obj);
539  if (objstate) {
540  tmp_tab = (GHashTable *)g_hash_table_lookup(objtype_objid_objstate_tab,
541  (gpointer)(uintptr_t)objtype);
542  g_hash_table_insert(tmp_tab,(gpointer)(uintptr_t)objid,objstate);
543  }
544 
545  ++monitor->objs;
546  ++monitor->live_objs;
547 
548  retval = 0;
549 
550  out:
551  return retval;
552 }
553 
554 int monitor_add_obj(struct monitor *monitor,int objid,int objtype,void *obj,
555  void *objstate) {
556  int retval;
557 
558  pthread_mutex_lock(&monitor_mutex);
559  pthread_mutex_lock(&monitor->mutex);
560 
561  retval = __monitor_add_obj(monitor,objid,objtype,obj,objstate);
562 
563  pthread_mutex_unlock(&monitor->mutex);
564  pthread_mutex_unlock(&monitor_mutex);
565 
566  return retval;
567 }
568 
569 static int __monitor_close_obj(struct monitor *monitor,
570  int objid,int objtype,void *obj,
571  int kill,int kill_sig,
572  GHashTable *iter_hashtable) {
573  int retval = 0;
574  struct monitor_objtype_ops *ops;
575  int _objtype = 0;
576  int _objid = 0;
577  void *_obj = NULL;
578  struct monitor *_monitor = NULL;
579  void *objstate;
580 
581  if (!(ops = __monitor_lookup_objtype_ops(objtype))) {
582  verror("unknown objtype %d!\n",objtype);
583  errno = EINVAL;
584  return -1;
585  }
586 
587  if (!__monitor_lookup_objid(objid,&_objtype,&_obj,&_monitor)) {
588  vwarn("objid %d (%p) not being monitored!\n",objid,obj);
589  errno = EINVAL;
590  return -1;
591  }
592 
593  if (!__monitor_lookup_obj(obj,&_objtype,&_objid,&_monitor)) {
594  vwarn("objid %d (%p) not being monitored!\n",objid,obj);
595  errno = EBUSY;
596  return -1;
597  }
598 
599  retval = 0;
600 
601  /* Detach the object. */
602  if (ops->evloop_is_attached && !ops->evloop_is_attached(monitor->evloop,obj)) {
603  ;
604  }
605  else if (ops->evloop_detach) {
606  if (ops->evloop_detach(monitor->evloop,obj) < 0) {
607  verror("error detaching evloop from objid %d (%p)!\n",objid,obj);
608  return -1;
609  }
610  }
611 
612  /* Close the object, with @sig. */
613  if (ops->close && ops->close(monitor,obj,objstate,kill,kill_sig)) {
614  verror("error closing objid %d (kill = %d, kill_sig %d)!\n",
615  objid,kill,kill_sig);
616  return -1;
617  }
618 
619  return retval;
620 }
621 
622 int monitor_close_obj(struct monitor *monitor,void *obj,
623  int kill,int kill_sig) {
624  int retval;
625  int objid = 0;
626  int objtype = 0;
627  struct monitor *_monitor = NULL;
628 
629  pthread_mutex_lock(&monitor_mutex);
630  pthread_mutex_lock(&monitor->mutex);
631 
632  if (!__monitor_lookup_obj(obj,&objtype,&objid,&_monitor) || !_monitor) {
633  verror("could not lookup obj %p!\n",obj);
634  errno = EINVAL;
635  pthread_mutex_unlock(&monitor->mutex);
636  pthread_mutex_unlock(&monitor_mutex);
637  return -1;
638  }
639 
640  retval = __monitor_close_obj(monitor,objid,objtype,obj,kill,kill_sig,NULL);
641 
642  pthread_mutex_unlock(&monitor->mutex);
643  pthread_mutex_unlock(&monitor_mutex);
644 
645  return retval;
646 }
647 
648 int monitor_close_objid(struct monitor *monitor,int objid,
649  int kill,int kill_sig) {
650  int retval;
651  void *obj = NULL;
652  int objtype = 0;
653  struct monitor *_monitor = NULL;
654 
655  pthread_mutex_lock(&monitor_mutex);
656  pthread_mutex_lock(&monitor->mutex);
657 
658  if (!__monitor_lookup_objid(objid,&objtype,&obj,&_monitor) || !_monitor) {
659  verror("could not lookup objid %d!\n",objid);
660  errno = EINVAL;
661  pthread_mutex_unlock(&monitor->mutex);
662  pthread_mutex_unlock(&monitor_mutex);
663  return -1;
664  }
665 
666  retval = __monitor_close_obj(monitor,objid,objtype,obj,kill,kill_sig,NULL);
667 
668  pthread_mutex_unlock(&monitor->mutex);
669  pthread_mutex_unlock(&monitor_mutex);
670 
671  return retval;
672 }
673 
674 static int __monitor_del_obj(struct monitor *monitor,
675  int objid,int objtype,void *obj,
676  GHashTable *iter_hashtable) {
677  int retval = -1;
678  struct monitor_objtype_ops *ops;
679  int _objtype = 0;
680  int _objid = 0;
681  void *_obj = NULL;
682  struct monitor *_monitor = NULL;
683  GHashTable *tmp_tab;
684  void *objstate;
685 
686  if (!(ops = __monitor_lookup_objtype_ops(objtype))) {
687  verror("unknown objtype %d!\n",objtype);
688  errno = EINVAL;
689  goto out;
690  }
691 
692  if (!__monitor_lookup_objid(objid,&_objtype,&_obj,&_monitor)) {
693  vwarn("objid %d (%p) not being monitored!\n",objid,obj);
694  errno = EINVAL;
695  goto out;
696  }
697 
698  if (!__monitor_lookup_obj(obj,&_objtype,&_objid,&_monitor)) {
699  vwarn("objid %d (%p) not being monitored!\n",objid,obj);
700  errno = EBUSY;
701  goto out;
702  }
703 
704  retval = 0;
705 
706  tmp_tab = (GHashTable *) \
707  g_hash_table_lookup(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype);
708  g_hash_table_remove(tmp_tab,(gpointer)(uintptr_t)objid);
709  tmp_tab = (GHashTable *)g_hash_table_lookup(objtype_objid_objstate_tab,
710  (gpointer)(uintptr_t)objtype);
711  objstate = g_hash_table_lookup(tmp_tab,(gpointer)(uintptr_t)objid);
712  g_hash_table_remove(tmp_tab,(gpointer)(uintptr_t)objid);
713 
714 
715  /* Detach the object. */
716  if (ops->evloop_is_attached && !ops->evloop_is_attached(monitor->evloop,obj)) {
717  ;
718  }
719  else if (ops->evloop_detach) {
720  if (ops->evloop_detach(monitor->evloop,obj) < 0) {
721  verror("could not detach evloop from objid %d (%p);"
722  " removing anyway!\n",objid,obj);
723  retval = -1;
724  }
725  }
726 
727  /* Close the object. */
728  if (ops->close && ops->close(monitor,obj,objstate,0,0)) {
729  verror("could not close objid %d; removing anyway!\n",objid);
730  retval = -1;
731  }
732 
733  /* Fini the object. */
734  if (ops->fini && ops->fini(monitor,obj,objstate)) {
735  verror("could not fini objid %d; removing anyway!\n",objid);
736  retval = -1;
737  }
738 
739  /*
740  * Remove it from all the hashtables.
741  */
742  if (iter_hashtable != obj_monitor_tab)
743  g_hash_table_remove(obj_monitor_tab,obj);
744  if (iter_hashtable != objid_monitor_tab)
745  g_hash_table_remove(objid_monitor_tab,(gpointer)(uintptr_t)objid);
746 
747  if (iter_hashtable != obj_objtype_tab)
748  g_hash_table_remove(obj_objtype_tab,obj);
749  if (iter_hashtable != objid_objtype_tab)
750  g_hash_table_remove(objid_objtype_tab,(gpointer)(uintptr_t)objid);
751 
752  if (iter_hashtable != objid_obj_tab)
753  g_hash_table_remove(objid_obj_tab,(gpointer)(uintptr_t)objid);
754  if (iter_hashtable != objid_obj_tab)
755  g_hash_table_remove(objid_obj_tab,obj);
756 
757  --monitor->objs;
758 
759  out:
760  return retval;
761 }
762 
763 int monitor_del_obj(struct monitor *monitor,void *obj) {
764  int retval;
765  int objid = 0;
766  int objtype = 0;
767  struct monitor *_monitor = NULL;
768 
769  pthread_mutex_lock(&monitor_mutex);
770  pthread_mutex_lock(&monitor->mutex);
771 
772  if (!__monitor_lookup_obj(obj,&objtype,&objid,&_monitor) || !_monitor) {
773  verror("could not lookup obj %p!\n",obj);
774  errno = EINVAL;
775  pthread_mutex_unlock(&monitor->mutex);
776  pthread_mutex_unlock(&monitor_mutex);
777  return -1;
778  }
779 
780  retval = __monitor_del_obj(monitor,objid,objtype,obj,NULL);
781 
782  pthread_mutex_unlock(&monitor->mutex);
783  pthread_mutex_unlock(&monitor_mutex);
784 
785  return retval;
786 }
787 
788 int monitor_del_objid(struct monitor *monitor,int objid) {
789  int retval;
790  void *obj = NULL;
791  int objtype = 0;
792  struct monitor *_monitor = NULL;
793 
794  pthread_mutex_lock(&monitor_mutex);
795  pthread_mutex_lock(&monitor->mutex);
796 
797  if (!__monitor_lookup_objid(objid,&objtype,&obj,&_monitor) || !_monitor) {
798  verror("could not lookup objid %d!\n",objid);
799  errno = EINVAL;
800  pthread_mutex_unlock(&monitor->mutex);
801  pthread_mutex_unlock(&monitor_mutex);
802  return -1;
803  }
804 
805  retval = __monitor_del_obj(monitor,objid,objtype,obj,NULL);
806 
807  pthread_mutex_unlock(&monitor->mutex);
808  pthread_mutex_unlock(&monitor_mutex);
809 
810  return retval;
811 }
812 
813 /*
814  * Keep this reentrant so it can be called many times without tracking
815  * the state of the monitor -- so NULL/-1/0 anything destroyed.
816  */
817 static int __monitor_shutdown(struct monitor *monitor) {
818  GHashTableIter iter;
819  gpointer obj;
820  int objid;
821  int objtype;
822  struct monitor *_monitor;
823 
824  /*
825  * Need to close all objs; gracefully shutdown evloop.
826  */
827 
828  if (monitor->mtid == 0) {
830  "monitor thread already gone, nothing to do\n");
831  return 0;
832  }
833 
834  if (!pthread_equal(pthread_self(),monitor->mtid)) {
835  verror("only monitor thread can shutdown itself!\n");
836  errno = EPERM;
837  return -1;
838  }
839 
840  vdebug(5,LA_LIB,LF_MONITOR,"shutting down monitor 0x%lx\n",monitor->mtid);
841 
842  /*
843  * Close all the objects.
844  */
845  g_hash_table_iter_init(&iter,obj_monitor_tab);
846  while (g_hash_table_iter_next(&iter,&obj,(gpointer *)&_monitor)) {
847  if (monitor == _monitor) {
848  if (!__monitor_lookup_obj(obj,&objtype,&objid,NULL))
849  verror("could not lookup obj %p to close it!\n",obj);
850  else {
851  vdebug(5,LA_LIB,LF_MONITOR,"closing objid %d\n",objid);
852  __monitor_close_obj(monitor,objid,objtype,obj,0,0,obj_monitor_tab);
853  }
854  }
855  }
856 
857  if (monitor->monitor_send_fd > -1) {
858  close(monitor->monitor_send_fd);
859  monitor->monitor_send_fd = -1;
860  }
861  if (monitor->child_recv_fd > -1) {
862  if (monitor->flags & MONITOR_FLAG_BIDI) {
863  /* This should have been closed when we forked the child... */
864  vwarn("BUG: child_recv_fd still live!\n");
865  }
866  close(monitor->child_recv_fd);
867  monitor->child_recv_fd = -1;
868  }
869 
870  if (monitor->flags & MONITOR_FLAG_BIDI) {
871  if (monitor->child_send_fd > -1) {
872  /* This should have been closed when we forked the child... */
873  vwarn("BUG: child_send_fd still live %d!\n",getpid());
874  close(monitor->child_send_fd);
875  monitor->child_send_fd = -1;
876  }
877  if (monitor->monitor_recv_fd > -1) {
878  close(monitor->monitor_recv_fd);
879  monitor->monitor_recv_fd = -1;
880  }
881  }
882 
883  if (monitor->type == MONITOR_TYPE_PROCESS) {
884  if (monitor->p.stdin_buf) {
885  free(monitor->p.stdin_buf);
886  monitor->p.stdin_buf = NULL;
887  }
888 
889  if (monitor->p.stdin_m_fd > -1) {
890  close(monitor->p.stdin_m_fd);
891  monitor->p.stdin_m_fd = -1;
892  }
893  if (monitor->p.stdin_c_fd > -1) {
894  /* This should have been closed when we forked the child... */
895  vwarn("BUG: p.stdin_c_fd still live!\n");
896  close(monitor->p.stdin_c_fd);
897  monitor->p.stdin_c_fd = -1;
898  }
899 
900  if (monitor->p.stdout_m_fd > -1) {
901  close(monitor->p.stdout_m_fd);
902  monitor->p.stdout_m_fd = -1;
903  }
904  if (monitor->p.stdout_c_fd > -1) {
905  /* This should have been closed when we forked the child... */
906  vwarn("BUG: p.stdout_c_fd still live!\n");
907  close(monitor->p.stdout_c_fd);
908  monitor->p.stdout_c_fd = -1;
909  }
910  if (monitor->p.stdout_log_fd > -1) {
911  close(monitor->p.stdout_log_fd);
912  monitor->p.stdout_log_fd = -1;
913  }
914 
915  if (monitor->p.stderr_m_fd > -1) {
916  close(monitor->p.stderr_m_fd);
917  monitor->p.stderr_m_fd = -1;
918  }
919  if (monitor->p.stderr_c_fd > -1) {
920  /* This should have been closed when we forked the child... */
921  vwarn("BUG: p.stderr_c_fd still live!\n");
922  close(monitor->p.stderr_c_fd);
923  monitor->p.stderr_c_fd = -1;
924  }
925  if (monitor->p.stderr_log_fd > -1) {
926  close(monitor->p.stderr_log_fd);
927  monitor->p.stderr_log_fd = -1;
928  }
929  }
930 
931  if (monitor->evloop) {
932  evloop_free(monitor->evloop);
933  monitor->evloop = NULL;
934  }
935 
936  /*
937  * Since this is the last function we can guarantee that the monitor
938  * thread will call (i.e., another thread could call
939  * monitor_destroy() if the monitor thread exits without calling
940  * it), we have to remove it from our thread -> monitor table here.
941  */
942  g_hash_table_remove(tid_monitor_tab,(gpointer)(uintptr_t)monitor->mtid);
943 
944  return 0;
945 }
946 
947 int monitor_shutdown(struct monitor *monitor) {
948  int rc;
949 
950  pthread_mutex_lock(&monitor_mutex);
951  pthread_mutex_lock(&monitor->mutex);
952 
953  rc = __monitor_shutdown(monitor);
954 
955  pthread_mutex_unlock(&monitor->mutex);
956  pthread_mutex_unlock(&monitor_mutex);
957 
958  return rc;
959 }
960 
961 static int __monitor_destroy(struct monitor *monitor) {
962  GHashTableIter iter;
963  gpointer obj;
964  int objid;
965  int objtype;
966  struct monitor *_monitor;
967  int found = 1;
968 
969  if (monitor->mtid == 0) {
971  "monitor thread already gone, nothing to do\n");
972  return 0;
973  }
974 
975  /*
976  * If the monitor thread is still running, only that thread can
977  * destroy the monitor. Otherwise, another thread can.
978  */
979  if (pthread_kill(monitor->mtid,0) == 0
980  && !pthread_equal(pthread_self(),monitor->mtid)) {
981  verror("only monitor thread can destroy itself!\n");
982  errno = EPERM;
983  return -1;
984  }
985 
986  vdebug(5,LA_LIB,LF_MONITOR,"destroying monitor 0x%lx\n",monitor->mtid);
987 
988  /* Make sure. */
989  __monitor_shutdown(monitor);
990 
991  /*
992  * Free all the objects.
993  */
994  while (found) {
995  found = 0;
996  g_hash_table_iter_init(&iter,obj_monitor_tab);
997  while (g_hash_table_iter_next(&iter,&obj,(gpointer *)&_monitor)) {
998  if (monitor == _monitor) {
999  found = 1;
1000 
1001  if (!__monitor_lookup_obj(obj,&objtype,&objid,NULL))
1002  verror("could not lookup obj %p to free it!\n",obj);
1003  else {
1004  vdebug(5,LA_LIB,LF_MONITOR,"freeing objid %d\n",objid);
1005  __monitor_del_obj(monitor,objid,objtype,obj,obj_monitor_tab);
1006  }
1007 
1008  g_hash_table_iter_remove(&iter);
1009 
1010  break;
1011  }
1012  }
1013  }
1014 
1015  if (monitor->msg_obj_tab) {
1016  g_hash_table_destroy(monitor->msg_obj_tab);
1017  monitor->msg_obj_tab = NULL;
1018  }
1019 
1020  /*
1021  * XXX: don't free the callback states; trust that they are
1022  * associated with a monitored object and will be freed that way.
1023  */
1024 
1025  if (monitor->p.stdout_logfile) {
1026  unlink(monitor->p.stdout_logfile);
1027  free(monitor->p.stdout_logfile);
1028  }
1029  if (monitor->p.stderr_logfile) {
1030  unlink(monitor->p.stderr_logfile);
1031  free(monitor->p.stderr_logfile);
1032  }
1033 
1034  free(monitor);
1035 
1036  return 0;
1037 }
1038 
1039 int monitor_destroy(struct monitor *monitor) {
1040  int rc;
1041 
1042  pthread_mutex_lock(&monitor_mutex);
1043  pthread_mutex_lock(&monitor->mutex);
1044 
1045  rc = __monitor_destroy(monitor);
1046 
1047  pthread_mutex_unlock(&monitor_mutex);
1048 
1049  return rc;
1050 }
1051 
1052 int monitor_register_objtype(int objtype,struct monitor_objtype_ops *ops,
1053  pthread_mutex_t *mutex) {
1054  pthread_mutex_lock(&monitor_mutex);
1055 
1056  if (g_hash_table_lookup(objtype_ops_tab,(gpointer)(uintptr_t)objtype)) {
1057  verror("monitor objtype %d already exists!\n",objtype);
1058  errno = EBUSY;
1059  pthread_mutex_unlock(&monitor_mutex);
1060  return -1;
1061  }
1062 
1063  g_hash_table_insert(objtype_ops_tab,(gpointer)(uintptr_t)objtype,ops);
1064  if (mutex)
1065  g_hash_table_insert(objtype_mutex_tab,(gpointer)(uintptr_t)objtype,
1066  mutex);
1067  g_hash_table_insert(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype,
1068  g_hash_table_new(g_direct_hash,g_direct_equal));
1069  g_hash_table_insert(objtype_objid_objstate_tab,(gpointer)(uintptr_t)objtype,
1070  g_hash_table_new(g_direct_hash,g_direct_equal));
1071 
1072  pthread_mutex_unlock(&monitor_mutex);
1073 
1074  return objtype;
1075 }
1076 
1077 int __monitor_recv_evh(int fd,int fdtype,void *state) {
1078  struct monitor *monitor = (struct monitor *)state;
1079  struct monitor_msg *msg;
1080  struct monitor_objtype_ops *ops;
1081  int retval = EVLOOP_HRET_SUCCESS;
1082  int objtype = -1;
1083  void *obj = NULL;
1084 
1085  /* XXX: need to hold monitor lock?! But cannot; we need to be done
1086  with global lock by the time we hold the monitor's lock. */
1087 
1088  /* XXX: don't bother checking if @fd == @monitor->monitor_reply_fd */
1089  msg = monitor_recv(monitor);
1090 
1091  if (!msg) {
1092  /*
1093  if (errno == EAGAIN || errno == EWOULDBLOCK) {
1094  vwarnopt(5,LA_LIB,LF_MONITOR,
1095  "could not recv msg on fd %d; but EAGAIN; ignoring!\n",fd);
1096  return retval;
1097  }
1098  */
1100  "could not recv msg on fd %d; closing!\n",fd);
1101  close(fd);
1102  monitor->monitor_recv_fd = -1;
1103  retval = EVLOOP_HRET_REMOVETYPE;
1104  goto out;
1105  }
1106 
1107  if (!monitor_lookup_objid(msg->objid,&objtype,&obj,NULL)) {
1109  "could not lookup objid %d; ignoring msg!\n",msg->objid);
1110  retval = EVLOOP_HRET_SUCCESS;
1111  goto out;
1112  }
1113 
1114  ops = monitor_lookup_objtype_ops(objtype);
1115  if (!ops) {
1117  "unknown objtype %d; ignoring msg!\n",objtype);
1118  retval = EVLOOP_HRET_SUCCESS;
1119  goto out;
1120  }
1121 
1123  "defhandler: recv type(%d) objid(%d) %d:%d '%s' (%d)\n",
1124  objtype,msg->objid,msg->id,msg->seqno,msg->msg,msg->len);
1125 
1126  if (ops->recv_msg) {
1127  ops->recv_msg(monitor,msg);
1128  return retval;
1129  }
1130 
1131  out:
1132  if (msg)
1133  monitor_msg_free(msg);
1134 
1135  return retval;
1136 }
1137 
1138 int __monitor_child_recv_evh(int fd,int fdtype,void *state) {
1139  struct monitor *monitor = (struct monitor *)state;
1140  struct monitor_msg *msg;
1141  struct monitor_objtype_ops *ops;
1142  int retval = EVLOOP_HRET_SUCCESS;
1143  int objtype = -1;
1144  void *obj = NULL;
1145 
1146  /* XXX: locking; see above function. */
1147 
1148  /* XXX: don't bother checking if @fd == @monitor->monitor_reply_fd */
1149  msg = monitor_child_recv(monitor);
1150 
1151  if (!msg) {
1153  "could not recv msg on fd %d; closing!\n",fd);
1154  close(fd);
1155  monitor->child_recv_fd = -1;
1156  retval = EVLOOP_HRET_REMOVETYPE;
1157  goto out;
1158  }
1159 
1160  if (!monitor_lookup_objid(msg->objid,&objtype,&obj,NULL)) {
1162  "could not lookup objid %d; ignoring msg!\n",msg->objid);
1163  retval = EVLOOP_HRET_SUCCESS;
1164  goto out;
1165  }
1166 
1167  ops = monitor_lookup_objtype_ops(objtype);
1168  if (!ops) {
1170  "unknown objtype %d; ignoring msg\n",objtype);
1171  retval = EVLOOP_HRET_SUCCESS;
1172  goto out;
1173  }
1174 
1176  "defhandler: recv type(%d) objid(%d) %hd:%hd '%s' (%d)\n",
1177  objtype,msg->objid,msg->id,msg->seqno,msg->msg,msg->len);
1178 
1179  if (ops && ops->child_recv_msg) {
1180  ops->child_recv_msg(monitor,msg);
1181  return retval;
1182  }
1183 
1184  out:
1185  if (msg)
1186  monitor_msg_free(msg);
1187 
1188  return retval;
1189 }
1190 
1191 int __safe_write(int fd,char *buf,int count) {
1192  int rc = 0;
1193  int retval;
1194 
1195  while (rc < count) {
1196  retval = write(fd,buf + rc,count - rc);
1197  if (retval < 0) {
1198  if (errno == EINTR)
1199  continue;
1200  else if (errno == EAGAIN || errno == EWOULDBLOCK) {
1201  return rc;
1202  }
1203  else {
1204  verror("write(%d): %s\n",fd,strerror(errno));
1205  return retval;
1206  }
1207  }
1208  else
1209  rc += retval;
1210  }
1211 
1212  return rc;
1213 }
1214 
1215 static int __monitor_stdout_evh(int fd,int fdtype,void *state) {
1216  struct monitor *monitor = (struct monitor *)state;
1217  int logfd = -1;
1218  monitor_stdio_callback_t callback;
1219  void *callback_state;
1220  char buf[256];
1221  int rc = 0;
1222  int retval;
1223  char *str = "out";
1224 
1225  if (fd == monitor->p.stdout_m_fd) {
1226  logfd = monitor->p.stdout_log_fd;
1227  callback = monitor->p.stdout_callback;
1228  callback_state = monitor->p.stdout_callback_state;
1229  }
1230  else if (fd == monitor->p.stderr_m_fd) {
1231  str = "err";
1232  logfd = monitor->p.stderr_log_fd;
1233  callback = monitor->p.stderr_callback;
1234  callback_state = monitor->p.stderr_callback_state;
1235  }
1236  else {
1237  verror("unknown stdout/err fd %d -- BUG!\n",fd);
1238  return EVLOOP_HRET_BADERROR;
1239  }
1240 
1241  while (rc < (int)sizeof(buf)) {
1242  retval = read(fd,buf + rc,sizeof(buf) - 1 - rc);
1243  if (retval < 0) {
1244  if (errno == EINTR)
1245  continue;
1246  else if (errno == EAGAIN || errno == EWOULDBLOCK) {
1247  /* Stop here; fire callback if we need */
1248  if (callback && rc) {
1249  buf[rc] = '\0';
1250  callback(fd,buf,rc,callback_state);
1251  }
1252  if (logfd > -1)
1253  __safe_write(logfd,buf,rc);
1254  return EVLOOP_HRET_SUCCESS;
1255  }
1256  else {
1257  verror("read(%d): %s (closing)\n",fd,strerror(errno));
1258  goto removetype;
1259  }
1260  }
1261  else if (retval == 0) {
1262  if (rc && callback) {
1263  buf[rc] = '\0';
1264  callback(fd,buf,rc,callback_state);
1265  }
1266  if (logfd > -1)
1267  __safe_write(logfd,buf,rc);
1268  vdebug(8,LA_LIB,LF_MONITOR,"closing std%s (%d) after EOF\n",str,fd);
1269  goto removetype;
1270  }
1271  else {
1272  rc += retval;
1273  if (rc == (sizeof(buf) - 1)) {
1274  if (callback) {
1275  buf[rc] = '\0';
1276  callback(fd,buf,rc,callback_state);
1277  }
1278  if (logfd > -1)
1279  __safe_write(logfd,buf,rc);
1280  rc = 0;
1281  }
1282  }
1283  }
1284 
1285  return EVLOOP_HRET_SUCCESS;
1286 
1287  removetype:
1288  close(fd);
1289  if (fd == monitor->p.stdout_m_fd) {
1290  monitor->p.stdout_m_fd = -1;
1291  monitor->p.stdout_callback = NULL;
1292  monitor->p.stdout_callback_state = NULL;
1293  }
1294  else if (fd == monitor->p.stderr_m_fd) {
1295  monitor->p.stderr_m_fd = -1;
1296  monitor->p.stderr_callback = NULL;
1297  monitor->p.stderr_callback_state = NULL;
1298  }
1299  return EVLOOP_HRET_REMOVETYPE;
1300 }
1301 
1302 static int __monitor_stdin_evh(int fd,int fdtype,void *state) {
1303  struct monitor *monitor = (struct monitor *)state;
1304  monitor_stdio_callback_t callback;
1305  void *callback_state;
1306  char buf[256];
1307  int rc = 0;
1308  int retval;
1309 
1310  if (fd == STDIN_FILENO) {
1311  callback = monitor->stdin_callback;
1312  callback_state = monitor->stdin_callback_state;
1313  }
1314  else {
1315  verror("unknown stdin fd %d -- BUG!\n",fd);
1316  return EVLOOP_HRET_BADERROR;
1317  }
1318 
1319  while (1) {
1320  retval = read(fd,buf + rc,sizeof(buf) - rc);
1321  if (retval < 0) {
1322  if (errno == EINTR)
1323  continue;
1324  else if (errno == EAGAIN || errno == EWOULDBLOCK) {
1325  /* Stop here; fire callback if we need */
1326  if (callback && rc) {
1327  buf[rc] = '\0';
1328  callback(fd,buf,rc,callback_state);
1329  }
1330  return EVLOOP_HRET_SUCCESS;
1331  }
1332  else {
1333  verror("read(%d): %s (closing)\n",fd,strerror(errno));
1334  close(fd);
1335  return EVLOOP_HRET_REMOVETYPE;
1336  }
1337  }
1338  else if (retval == 0) {
1339  if (rc && callback) {
1340  buf[rc] = '\0';
1341  callback(fd,buf,rc,callback_state);
1342  }
1343  vdebug(8,LA_LIB,LF_MONITOR,"closing stdin after EOF\n",fd);
1344  close(fd);
1346  }
1347  else {
1348  rc += retval;
1349  if (retval == sizeof(buf)) {
1350  if (callback) {
1351  buf[rc] = '\0';
1352  callback(fd,buf,rc,callback_state);
1353  }
1354  rc = 0;
1355  }
1356  }
1357  }
1358 
1359  return EVLOOP_HRET_SUCCESS;
1360 }
1361 
1362 static int __monitor_eh(int errortype,int fd,int fdtype,
1363  struct evloop_fdinfo *fdinfo) {
1364  struct monitor *monitor = NULL;
1365 
1366  if (fdtype == EVLOOP_FDTYPE_R)
1367  monitor = (struct monitor *)fdinfo->rhstate;
1368  else if (fdtype == EVLOOP_FDTYPE_W)
1369  monitor = (struct monitor *)fdinfo->whstate;
1370  if (fdtype == EVLOOP_FDTYPE_X)
1371  monitor = (struct monitor *)fdinfo->xhstate;
1372 
1373  if (!monitor) {
1374  verror("no monitor state to handle evloop error -- double fault!\n");
1375  return EVLOOP_HRET_BADERROR;
1376  }
1377 
1378  /*
1379  * If it happened on one of our descriptors, warn that way -- that
1380  * would be our BUG!
1381  *
1382  * If it happened on an "unknown" one, it happened on one of our
1383  * objects; so the objtype handler needs to be fixed!
1384  */
1385  if (fd == monitor->monitor_send_fd
1386  || fd == monitor->monitor_recv_fd
1387  || fd == monitor->child_recv_fd
1388  || fd == monitor->child_send_fd) {
1389  verror("BUG: error on monitor pipe fd %d: %d\n",fd,errortype);
1390  }
1391  else if (fd == monitor->p.pid_waitpipe_fd) {
1392  verror("BUG: error on monitor child pid waitpipe fd %d: %d\n",
1393  fd,errortype);
1394  }
1395  else if (fd == monitor->p.stdin_m_fd || fd == monitor->p.stdin_c_fd
1396  || fd == monitor->p.stdout_m_fd || fd == monitor->p.stdout_c_fd
1397  || fd == monitor->p.stderr_m_fd || fd == monitor->p.stderr_c_fd) {
1398  verror("BUG: error on monitor stdio fd %d: %d\n",fd,errortype);
1399  }
1400  else {
1401  verror("BUG: evloop error on a non-monitor descriptor %d: %d\n",
1402  fd,errortype);
1403  }
1404 
1405  return EVLOOP_HRET_BADERROR;
1406 }
1407 
1408 int __monitor_add_primary_obj(struct monitor *monitor,
1409  int objid,int objtype,void *obj,void *objstate);
1410 
1412  int objid,int objtype,void *obj,void *objstate,
1413  evloop_handler_t custom_recv_evh,
1414  evloop_handler_t custom_child_recv_evh) {
1415  struct monitor *monitor;
1416  struct monitor_objtype_ops *ops;
1417  int req_pipe[2] = { -1,-1 };
1418  int rep_pipe[2] = { -1,-1 };
1419 
1420  if (type != MONITOR_TYPE_THREAD && type != MONITOR_TYPE_PROCESS) {
1421  verror("unknown monitor type %d\n",type);
1422  errno = EINVAL;
1423  return NULL;
1424  }
1425  else if (type == MONITOR_TYPE_PROCESS) {
1426  /*
1427  * Need to ensure init waitpipe(). We don't need an extra sighandler.
1428  */
1429  if (!waitpipe_is_initialized())
1430  waitpipe_init_auto(NULL);
1431  }
1432 
1433  if (!(ops = monitor_lookup_objtype_ops(objtype))) {
1434  verror("unknown objtype %d!\n",objtype);
1435  errno = EINVAL;
1436  return NULL;
1437  }
1438 
1439  monitor = calloc(1,sizeof(*monitor));
1440 
1441  monitor->type = type;
1442  monitor->flags = flags;
1443  monitor->mtid = pthread_self();
1444 
1445  pthread_mutex_init(&monitor->mutex,NULL);
1446 
1447  monitor->msg_obj_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
1448  pthread_mutex_init(&monitor->msg_obj_tab_mutex,NULL);
1449 
1450  monitor->evloop = evloop_create(__monitor_eh);
1451 
1452  if (pipe(req_pipe)) {
1453  verror("pipe: %s\n",strerror(errno));
1454  goto errout;
1455  }
1456  monitor->monitor_send_fd = req_pipe[1];
1457  fcntl(monitor->monitor_send_fd,F_SETFD,FD_CLOEXEC);
1458  monitor->child_recv_fd = req_pipe[0];
1459 
1460  monitor->p.pid = -1;
1461 
1462  if (flags & MONITOR_FLAG_BIDI) {
1463  if (pipe(rep_pipe)) {
1464  verror("pipe: %s\n",strerror(errno));
1465  goto errout;
1466  }
1467  monitor->child_send_fd = rep_pipe[1];
1468  monitor->monitor_recv_fd = rep_pipe[0];
1469  fcntl(monitor->monitor_recv_fd,F_SETFD,FD_CLOEXEC);
1470  }
1471  else {
1472  monitor->child_send_fd = -1;
1473  monitor->monitor_recv_fd = -1;
1474  }
1475 
1476  /*
1477  * Set up @monitor->evloop with our default handler if this is a
1478  * thread-based monitor, because the client and monitor are in the
1479  * same thread :). For processes, we do nothing, because the
1480  * process does not have the child end of the pipes; the child
1481  * process has those.
1482  */
1483  if (type == MONITOR_TYPE_THREAD && monitor->child_recv_fd > -1) {
1484  if (custom_child_recv_evh)
1485  evloop_set_fd(monitor->evloop,
1486  monitor->child_recv_fd,EVLOOP_FDTYPE_R,
1487  custom_child_recv_evh,monitor);
1488  else
1489  evloop_set_fd(monitor->evloop,
1490  monitor->child_recv_fd,EVLOOP_FDTYPE_R,
1491  __monitor_child_recv_evh,monitor);
1492 
1493  }
1494 
1495  /*
1496  * Set up @monitor->evloop with our default handler if this is a
1497  * bidirectional monitor.
1498  */
1499  if (monitor->monitor_recv_fd > -1) {
1500  if (custom_recv_evh)
1501  evloop_set_fd(monitor->evloop,
1503  custom_recv_evh,monitor);
1504  else
1505  evloop_set_fd(monitor->evloop,
1507  __monitor_recv_evh,monitor);
1508  }
1509 
1510  vdebug(4,LA_LIB,LF_MONITOR,"msfd=%d,crfd=%d,csfd=%d,mrfd=%d\n",
1511  monitor->monitor_send_fd,monitor->child_recv_fd,
1512  monitor->child_send_fd,monitor->monitor_recv_fd);
1513 
1514  /* These are initialized by calling monitor_setup_io if necessary. */
1515  monitor->p.stdin_m_fd = -1;
1516  monitor->p.stdin_c_fd = -1;
1517  monitor->p.stdout_m_fd = -1;
1518  monitor->p.stdout_c_fd = -1;
1519  monitor->p.stdout_log_fd = -1;
1520  monitor->p.stderr_m_fd = -1;
1521  monitor->p.stderr_c_fd = -1;
1522  monitor->p.stderr_log_fd = -1;
1523 
1524  pthread_mutex_lock(&monitor_mutex);
1525  pthread_mutex_lock(&monitor->mutex);
1526 
1527  g_hash_table_insert(tid_monitor_tab,
1528  (gpointer)(uintptr_t)monitor->mtid,monitor);
1529 
1530  if (obj && __monitor_add_primary_obj(monitor,objid,objtype,obj,objstate)) {
1531  pthread_mutex_unlock(&monitor->mutex);
1532  pthread_mutex_unlock(&monitor_mutex);
1533  goto errout;
1534  }
1535 
1536  pthread_mutex_unlock(&monitor->mutex);
1537  pthread_mutex_unlock(&monitor_mutex);
1538 
1539  return monitor;
1540 
1541  errout:
1542  if (monitor->msg_obj_tab)
1543  g_hash_table_destroy(monitor->msg_obj_tab);
1544  if (monitor->evloop)
1545  evloop_free(monitor->evloop);
1546  if (req_pipe[0] > -1)
1547  close(req_pipe[0]);
1548  if (req_pipe[1] > -1)
1549  close(req_pipe[1]);
1550  if (rep_pipe[0] > -1)
1551  close(rep_pipe[0]);
1552  if (rep_pipe[1] > -1)
1553  close(rep_pipe[1]);
1554  free(monitor);
1555 
1556  return NULL;
1557 }
1558 
1559 int __monitor_add_primary_obj(struct monitor *monitor,
1560  int objid,int objtype,void *obj,void *objstate) {
1561  /*
1562  * Save the primary object directly in the monitor.
1563  */
1564  monitor->objid = objid;
1565  monitor->obj = obj;
1566 
1567  if (__monitor_add_obj(monitor,monitor->objid,objtype,obj,objstate)) {
1568  monitor->objid = -1;
1569  monitor->obj = NULL;
1570  return -1;
1571  }
1572 
1573  return 0;
1574 }
1575 
1576 int monitor_add_primary_obj(struct monitor *monitor,
1577  int objid,int objtype,void *obj,void *objstate) {
1578  int retval;
1579 
1580  /*
1581  * Grab our locks.
1582  */
1583  pthread_mutex_lock(&monitor_mutex);
1584  pthread_mutex_lock(&monitor->mutex);
1585 
1586  retval = __monitor_add_primary_obj(monitor,objid,objtype,obj,objstate);
1587 
1588  pthread_mutex_unlock(&monitor->mutex);
1589  pthread_mutex_unlock(&monitor_mutex);
1590 
1591  return retval;
1592 }
1593 
1595  int objid,int objtype,void *obj,void *objstate) {
1596  struct monitor *monitor;
1597 
1598  monitor = monitor_create_custom(type,flags,objid,objtype,obj,objstate,NULL,NULL);
1599 
1600  return monitor;
1601 }
1602 
1604  if (getenv(MONITOR_CHILD_RECV_FD_ENVVAR))
1605  return 1;
1606  return 0;
1607 }
1608 
1610  if (getenv(MONITOR_CHILD_RECV_FD_ENVVAR)
1611  && getenv(MONITOR_CHILD_SEND_FD_ENVVAR))
1612  return 1;
1613  return 0;
1614 }
1615 
1617  int objtype,void *obj,void *objstate,
1618  evloop_handler_t custom_child_recv_evh,
1620  void *callback_state) {
1621  struct monitor *monitor;
1622 
1623  if (type != MONITOR_TYPE_PROCESS) {
1624  verror("can only attach to process-based monitors! (%d)\n",type);
1625  errno = EINVAL;
1626  return NULL;
1627  }
1628 
1629  /*
1630  * We could check the env vars, and fail if we can't get them, but
1631  * we don't in this case. We want to allow "headless" monitor
1632  * childs through.
1633  */
1634 
1635  monitor = calloc(1,sizeof(*monitor));
1636 
1637  monitor->type = type;
1638  monitor->flags = flags;
1639  monitor->mtid = pthread_self();
1640 
1641  monitor->obj = obj;
1642 
1643  pthread_mutex_init(&monitor->mutex,NULL);
1644 
1645  monitor->msg_obj_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
1646  pthread_mutex_init(&monitor->msg_obj_tab_mutex,NULL);
1647 
1648  if (getenv(MONITOR_OBJID_ENVVAR)) {
1649  vdebug(5,LA_LIB,LF_MONITOR,"child objid is %s\n",
1650  getenv(MONITOR_OBJID_ENVVAR));
1651  monitor->objid = atoi(getenv(MONITOR_OBJID_ENVVAR));
1652  /* Don't want any children to inherit this... */
1653  fcntl(monitor->child_recv_fd,F_SETFD,FD_CLOEXEC);
1654  }
1655  else {
1656  verror("no objid set by parent!\n");
1657  free(monitor);
1658  errno = EINVAL;
1659  return NULL;
1660  }
1661 
1662  if (getenv(MONITOR_CHILD_RECV_FD_ENVVAR)) {
1663  vdebug(5,LA_LIB,LF_MONITOR,"child recv fd is %s\n",
1665  monitor->child_recv_fd = atoi(getenv(MONITOR_CHILD_RECV_FD_ENVVAR));
1666  /* Don't want any children to inherit this... */
1667  fcntl(monitor->child_recv_fd,F_SETFD,FD_CLOEXEC);
1668  }
1669  else
1670  monitor->child_recv_fd = -1;
1671 
1672  if (getenv(MONITOR_CHILD_SEND_FD_ENVVAR)) {
1673  vdebug(5,LA_LIB,LF_MONITOR,"child send fd is %s\n",
1675  monitor->child_send_fd = atoi(getenv(MONITOR_CHILD_SEND_FD_ENVVAR));
1676  /* Don't want any children to inherit this... */
1677  if (monitor->child_send_fd > -1) {
1678  fcntl(monitor->child_send_fd,F_SETFD,FD_CLOEXEC);
1679 
1680  if (!(flags & MONITOR_FLAG_BIDI)) {
1681  close(monitor->child_send_fd);
1682  monitor->child_send_fd = -1;
1683  }
1684  }
1685  else if (flags & MONITOR_FLAG_BIDI) {
1686  vwarn("could not enable bidirectional communication; bad envvar fd!\n");
1687  monitor->flags &= ~MONITOR_FLAG_BIDI;
1688  }
1689  }
1690  else {
1691  if (flags & MONITOR_FLAG_BIDI) {
1692  vwarn("could not enable bidirectional communication; no envvar fd!\n");
1693  monitor->flags &= ~MONITOR_FLAG_BIDI;
1694  }
1695  monitor->child_send_fd = -1;
1696  }
1697 
1698  monitor->evloop = evloop_create(__monitor_eh);
1699 
1700  /* Only process-based monitor children can call this, so we do not
1701  * listen on anything else.
1702  */
1703  if (monitor->child_recv_fd > -1) {
1704  if (custom_child_recv_evh)
1705  evloop_set_fd(monitor->evloop,
1706  monitor->child_recv_fd,EVLOOP_FDTYPE_R,
1707  custom_child_recv_evh,monitor);
1708  else
1709  evloop_set_fd(monitor->evloop,
1710  monitor->child_recv_fd,EVLOOP_FDTYPE_R,
1711  __monitor_child_recv_evh,monitor);
1712  }
1713 
1714  monitor->p.stdin_m_fd = -1;
1715  monitor->p.stdin_c_fd = -1;
1716  monitor->p.stdout_m_fd = -1;
1717  monitor->p.stdout_c_fd = -1;
1718  monitor->p.stdout_log_fd = -1;
1719  monitor->p.stderr_m_fd = -1;
1720  monitor->p.stderr_c_fd = -1;
1721  monitor->p.stderr_log_fd = -1;
1722 
1723  /* XXX: really should try to check if stdin will have input */
1724  evloop_set_fd(monitor->evloop,STDIN_FILENO,EVLOOP_FDTYPE_R,
1725  __monitor_stdin_evh,monitor);
1726  monitor->stdin_callback = stdin_callback;
1727 
1728  /*
1729  * Now grab our locks.
1730  */
1731  pthread_mutex_lock(&monitor_mutex);
1732  pthread_mutex_lock(&monitor->mutex);
1733 
1734  /*
1735  * Add the primary object.
1736  */
1737  if (obj && __monitor_add_obj(monitor,monitor->objid,objtype,obj,objstate)) {
1738  pthread_mutex_unlock(&monitor->mutex);
1739  pthread_mutex_unlock(&monitor_mutex);
1740  goto errout;
1741  }
1742 
1743  pthread_mutex_unlock(&monitor->mutex);
1744  pthread_mutex_unlock(&monitor_mutex);
1745 
1746  return monitor;
1747 
1748  errout:
1749  if (monitor->msg_obj_tab)
1750  g_hash_table_destroy(monitor->msg_obj_tab);
1751  if (monitor->evloop)
1752  evloop_free(monitor->evloop);
1753  /*
1754  * Don't close the pipes; there cannot have been an error involving
1755  * them. Let the user retry if they want.
1756  */
1757  free(monitor);
1758 
1759  return monitor;
1760 }
1761 
1762 int __monitor_send_stdin_evh(int fd,int fdtype,void *state) {
1763  struct monitor *monitor = (struct monitor *)state;
1764  int retval;
1765 
1766  if (monitor->p.stdin_left <= 0) {
1767  vwarn("called again even with no input remaining!\n");
1769  }
1770 
1771  again:
1772  retval = write(monitor->p.stdin_m_fd,
1773  monitor->p.stdin_buf + \
1774  (monitor->p.stdin_bufsiz - monitor->p.stdin_left),
1775  monitor->p.stdin_left);
1776  if (retval < 0) {
1777  if (errno == EAGAIN || errno == EWOULDBLOCK)
1778  return EVLOOP_HRET_SUCCESS;
1779  else if (errno == EINTR)
1780  goto again;
1781  else if (errno == EPIPE) {
1782  vwarn("child closed read stdin unexpectedly?\n");
1783  /* XXX: do something more informative? */
1784  return EVLOOP_HRET_BADERROR;
1785  }
1786  else {
1787  verror("error(wrote %d of %d bytes stdin): write: %s\n",
1788  monitor->p.stdin_bufsiz - monitor->p.stdin_left,
1789  monitor->p.stdin_bufsiz,strerror(errno));
1791  }
1792  }
1793  else {
1794  monitor->p.stdin_left -= retval;
1795  vdebug(8,LA_LIB,LF_MONITOR,"wrote %d of %d bytes stdin\n",
1796  monitor->p.stdin_bufsiz - monitor->p.stdin_left,
1797  monitor->p.stdin_bufsiz);
1798 
1799  if (monitor->p.stdin_left <= 0) {
1800  vdebug(8,LA_LIB,LF_MONITOR,"finished writing %d bytes stdin\n",
1801  monitor->p.stdin_bufsiz);
1802 
1803  monitor->p.stdin_left = monitor->p.stdin_bufsiz = -1;
1804 
1805  free(monitor->p.stdin_buf);
1806  monitor->p.stdin_buf = NULL;
1807  close(monitor->p.stdin_m_fd);
1808  monitor->p.stdin_m_fd = -1;
1809 
1811  }
1812  }
1813 
1814  return EVLOOP_HRET_SUCCESS;
1815 }
1816 
1817 int monitor_setup_stdin(struct monitor *monitor,
1818  char *stdin_buf,int stdin_buflen) {
1819  int pipefds[2] = { -1,-1 };
1820 
1821  if (monitor->type != MONITOR_TYPE_PROCESS) {
1822  errno = EINVAL;
1823  verror("invalid monitor type %d\n",monitor->type);
1824  return -1;
1825  }
1826 
1827  if (pipe(pipefds)) {
1828  verror("pipe: %s\n",strerror(errno));
1829  return -1;
1830  }
1831  monitor->p.stdin_m_fd = pipefds[1];
1832  fcntl(monitor->p.stdin_m_fd,F_SETFD,FD_CLOEXEC);
1833  /*
1834  * Also open this one nonblocking because we don't want the monitor
1835  * thread to block while sending input to the child.
1836  */
1837  fcntl(pipefds[1],F_SETFL,fcntl(pipefds[1],F_GETFL) | O_NONBLOCK);
1838  monitor->p.stdin_c_fd = pipefds[0];
1839 
1840  monitor->p.stdin_buf = stdin_buf;
1841  monitor->p.stdin_left = stdin_buflen;
1842  monitor->p.stdin_bufsiz = stdin_buflen;
1843 
1844  return 0;
1845 }
1846 
1847 int monitor_setup_stdout(struct monitor *monitor,
1848  int maxbufsiz,char *stdout_logfile,
1850  void *callback_state) {
1851  int pipefds[2] = { -1,-1 };
1852 
1853  if (monitor->type != MONITOR_TYPE_PROCESS) {
1854  errno = EINVAL;
1855  verror("invalid monitor type %d\n",monitor->type);
1856  return -1;
1857  }
1858 
1859  if (stdout_logfile) {
1860  monitor->p.stdout_log_fd = \
1861  open(stdout_logfile,O_RDWR | O_CREAT | O_APPEND | O_TRUNC,
1862  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1863  if (monitor->p.stdout_log_fd < 0) {
1864  verror("could not open stdout logfile %s!\n",stdout_logfile);
1865  return -1;
1866  }
1867  monitor->p.stdout_logfile = strdup(stdout_logfile);
1868  }
1869 
1870  if (pipe(pipefds)) {
1871  verror("pipe: %s\n",strerror(errno));
1872  if (monitor->p.stdout_log_fd != -1)
1873  close(monitor->p.stdout_log_fd);
1874  return -1;
1875  }
1876  monitor->p.stdout_c_fd = pipefds[1];
1877  monitor->p.stdout_m_fd = pipefds[0];
1878  fcntl(monitor->p.stdout_m_fd,F_SETFD,FD_CLOEXEC);
1879  /*
1880  * Also open this one nonblocking because we don't want the monitor
1881  * thread to block while reading output from the child.
1882  */
1883  fcntl(monitor->p.stdout_m_fd,F_SETFL,
1884  fcntl(monitor->p.stdout_m_fd,F_GETFL) | O_NONBLOCK);
1885 
1886  /*
1887  if (maxbufsiz > 0)
1888  monitor->p.stdout_buf = cbuf_alloc(maxbufsiz,-1);
1889  */
1890 
1891  monitor->p.stdout_callback = stdout_callback;
1892  monitor->p.stdout_callback_state = callback_state;
1893 
1894  return 0;
1895 }
1896 
1897 int monitor_setup_stderr(struct monitor *monitor,
1898  int maxbufsiz,char *stderr_logfile,
1900  void *callback_state) {
1901  int pipefds[2] = { -1,-1 };
1902 
1903  if (monitor->type != MONITOR_TYPE_PROCESS) {
1904  errno = EINVAL;
1905  verror("invalid monitor type %d\n",monitor->type);
1906  return -1;
1907  }
1908 
1909  if (stderr_logfile) {
1910  monitor->p.stderr_log_fd = \
1911  open(stderr_logfile,O_RDWR | O_CREAT | O_APPEND | O_TRUNC,
1912  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1913  if (monitor->p.stderr_log_fd < 0) {
1914  verror("could not open stderr logfile %s!\n",stderr_logfile);
1915  return -1;
1916  }
1917  monitor->p.stderr_logfile = strdup(stderr_logfile);
1918  }
1919 
1920  if (pipe(pipefds)) {
1921  verror("pipe: %s\n",strerror(errno));
1922  if (monitor->p.stderr_log_fd != -1)
1923  close(monitor->p.stderr_log_fd);
1924  return -1;
1925  }
1926  monitor->p.stderr_c_fd = pipefds[1];
1927  monitor->p.stderr_m_fd = pipefds[0];
1928  fcntl(monitor->p.stderr_m_fd,F_SETFD,FD_CLOEXEC);
1929  /*
1930  * Also open this one nonblocking because we don't want the monitor
1931  * thread to block while reading output from the child.
1932  */
1933  fcntl(monitor->p.stderr_m_fd,F_SETFL,
1934  fcntl(monitor->p.stderr_m_fd,F_GETFL) | O_NONBLOCK);
1935 
1936  /*
1937  if (maxbufsiz > 0)
1938  monitor->p.stderr_buf = cbuf_alloc(maxbufsiz,-1);
1939  */
1940 
1941  monitor->p.stderr_callback = stderr_callback;
1942  monitor->p.stderr_callback_state = callback_state;
1943 
1944  return 0;
1945 }
1946 
1947 static int __monitor_pid_evh(int fd,int fdtype,void *state) {
1948  struct monitor *monitor = (struct monitor *)state;
1949  int pid = monitor->p.pid;
1950  int status = 0;
1951 
1952  /*
1953  * The waitpipe tells us that the pid has status to wait for; wait
1954  * for it and save its status.
1955  */
1956 
1957  if (waitpid(pid,&status,0) < 0) {
1958  verror("waitpid(%d): %s; continuing but sig may be lost!\n",
1959  pid,strerror(errno));
1960  return EVLOOP_HRET_DONE_SUCCESS;
1961  }
1962 
1963  if (WIFCONTINUED(status)) {
1965  "monitored child %d CONTinued; ignoring\n",pid);
1966  return EVLOOP_HRET_DONE_SUCCESS;
1967  }
1968  else if (WIFSTOPPED(status)) {
1970  "monitored child %d STOPped; ignoring\n",pid);
1971  return EVLOOP_HRET_DONE_SUCCESS;
1972  }
1973  else if (WIFSIGNALED(status)) {
1975  "monitored child %d terminated by signal %d\n",
1976  pid,WTERMSIG(status));
1977  }
1978  else if (WIFEXITED(status)) {
1980  "monitored child %d exited with status %d (0x%x)\n",
1981  pid,WEXITSTATUS(status),WEXITSTATUS(status));
1982  }
1983  else {
1984  verror("waitpid(%d): unrecognized status; ignoring!\n",pid);
1985  return EVLOOP_HRET_DONE_SUCCESS;
1986  }
1987 
1988  /* nuke the pipe */
1989  waitpipe_remove(pid);
1990 
1991  /* save status */
1992  monitor->p.status = status;
1993 
1994  monitor->p.pid_waitpipe_fd = -1;
1995 
1996  /* remove ALL the fds from the event loop */
1997  return EVLOOP_HRET_DONE_SUCCESS;
1998 }
1999 
2000 extern char **environ;
2001 
2002 int monitor_spawn(struct monitor *monitor,char *filename,
2003  char *const argv[],char *const envp[],char *dir) {
2004  int pid;
2005  char envvarbuf[64];
2006  int envlen;
2007  char **envp_actual;
2008  char cwd[PATH_MAX];
2009  int i;
2010  char **sptr;
2011  sigset_t set;
2012 
2013  if (monitor->type != MONITOR_TYPE_PROCESS) {
2014  verror("cannot handle a non-MONITOR_TYPE_PROCESS!\n");
2015  errno = EINVAL;
2016  return -1;
2017  }
2018 
2019  if (dir) {
2020  if (!getcwd(cwd,PATH_MAX)) {
2021  verror("getcwd: %s\n",strerror(errno));
2022  return -1;
2023  }
2024  if (chdir(dir)) {
2025  verror("chdir(%s): %s!\n",dir,strerror(errno));
2026  return -1;
2027  }
2028  }
2029 
2030  pid = fork();
2031 
2032  if (pid < 0) {
2033  verror("fork: %s\n",strerror(errno));
2034  return pid;
2035  }
2036  else if (!pid) {
2037  /* Setup env vars. Extend our current env if they don't pass one. */
2038  envlen = 0;
2039  i = 0;
2040  if (!envp)
2041  envp = environ;
2042  if (envp) {
2043  while (envp[i++])
2044  ++envlen;
2045  }
2046 
2047  envp_actual = calloc(envlen + 4,sizeof(char *));
2048 
2049  i = 0;
2050  if (envp) {
2051  while (i < envlen) {
2052  envp_actual[i] = envp[i];
2053  ++i;
2054  }
2055  }
2056 
2057  /* Tell the child it is monitored, and tell it its FDs. */
2058  if (monitor->child_recv_fd > -1) {
2059  snprintf(envvarbuf,sizeof(envvarbuf),"%s=%d",
2061  envp_actual[i] = strdup(envvarbuf);
2062  ++i;
2063  envp_actual[i] = NULL;
2064  }
2065  if (monitor->child_send_fd > -1) {
2066  snprintf(envvarbuf,sizeof(envvarbuf),"%s=%d",
2068  envp_actual[i] = strdup(envvarbuf);
2069  ++i;
2070  envp_actual[i] = NULL;
2071  }
2072  /* Also tell it its primary monitored object id */
2073  snprintf(envvarbuf,sizeof(envvarbuf),"%s=%d",
2074  MONITOR_OBJID_ENVVAR,monitor->objid);
2075  envp_actual[i] = strdup(envvarbuf);
2076  ++i;
2077  envp_actual[i] = NULL;
2078 
2079  /*
2080  * Setup stdio streams.
2081  */
2082  if (monitor->p.stdin_c_fd > -1) {
2083  if (dup2(monitor->p.stdin_c_fd,STDIN_FILENO)) {
2084  verror("dup2(%d,stdin): %s; closing stdin!\n",
2085  monitor->p.stdin_c_fd,strerror(errno));
2086  close(STDIN_FILENO);
2087  }
2088  }
2089  else {
2090  close(STDIN_FILENO);
2091  }
2092 
2093  if (monitor->p.stdout_c_fd > -1) {
2094  if (dup2(monitor->p.stdout_c_fd,STDOUT_FILENO) < 0) {
2095  verror("dup2(%d,stdout): %s; ignoring!\n",
2096  monitor->p.stdout_c_fd,strerror(errno));
2097  }
2098  }
2099 
2100  if (monitor->p.stderr_c_fd > -1) {
2101  if (dup2(monitor->p.stderr_c_fd,STDERR_FILENO) < 0) {
2102  verror("dup2(%d,stderr): %s; ignoring!\n",
2103  monitor->p.stderr_c_fd,strerror(errno));
2104  }
2105  }
2106 
2107  /*
2108  * XXX: cleanup any monitor-only state!
2109  */
2110 
2111  vdebug(3,LA_LIB,LF_MONITOR,"execve(%s) in %s\n",filename,dir);
2112  if (vdebug_is_on(2,LA_LIB,LF_MONITOR)) {
2113  if (argv) {
2114  vdebug(3,LA_LIB,LF_MONITOR,"execve(argv=[");
2115  sptr = argv;
2116  while (sptr && *sptr) {
2117  vdebugc(3,LA_LIB,LF_MONITOR,"'%s',",*sptr);
2118  ++sptr;
2119  }
2120  vdebugc(3,LA_LIB,LF_MONITOR,"])\n");
2121  }
2122  if (envp_actual) {
2123  vdebug(3,LA_LIB,LF_MONITOR,"execve(envp=[");
2124  sptr = envp_actual;
2125  while (sptr && *sptr) {
2126  vdebugc(3,LA_LIB,LF_MONITOR,"'%s',",*sptr);
2127  ++sptr;
2128  }
2129  vdebugc(3,LA_LIB,LF_MONITOR,"])\n");
2130  }
2131  }
2132 
2133  /* Make sure to reset the signal mask; some of our users mask things. */
2134  sigprocmask(0,NULL,&set);
2135  sigprocmask(SIG_UNBLOCK,(const sigset_t *)&set,NULL);
2136 
2137  setsid();
2138 
2139  if (execve(filename,argv,envp_actual)) {
2140  verror("execve(%s): %s!\n",filename,strerror(errno));
2141  return -1;
2142  }
2143  }
2144  else {
2145  monitor->p.pid = pid;
2146 
2147  ++monitor->live_children;
2148 
2149  /* Change dir back if we need. */
2150  if (dir && chdir(cwd)) {
2151  verror("chdir(%s): %s!\n",cwd,strerror(errno));
2152  // XXX: do not exit; this should not happen; trust it won't.
2153  }
2154 
2155  /*
2156  * Add our default handlers for stderr/stdout if necessary.
2157  */
2158  if (monitor->p.stdout_m_fd > -1)
2159  evloop_set_fd(monitor->evloop,monitor->p.stdout_m_fd,
2160  EVLOOP_FDTYPE_R,__monitor_stdout_evh,monitor);
2161  if (monitor->p.stderr_m_fd > -1)
2162  evloop_set_fd(monitor->evloop,monitor->p.stderr_m_fd,
2163  EVLOOP_FDTYPE_R,__monitor_stdout_evh,monitor);
2164  /* Make sure to send our stdin to the child. */
2165  if (monitor->p.stdin_m_fd > -1)
2166  evloop_set_fd(monitor->evloop,monitor->p.stdin_m_fd,EVLOOP_FDTYPE_W,
2167  __monitor_send_stdin_evh,monitor);
2168 
2169  /*
2170  * Add a waitpipe handler for the child.
2171  */
2172  monitor->p.pid_waitpipe_fd = waitpipe_add(pid);
2173  if (monitor->p.pid_waitpipe_fd < 0) {
2174  if (errno == EINVAL) {
2175  verror("could not wait on pid %d: %s; continuing anyway!\n",
2176  pid,strerror(errno));
2177  }
2178  }
2179  else {
2180  evloop_set_fd(monitor->evloop,monitor->p.pid_waitpipe_fd,
2181  EVLOOP_FDTYPE_R,__monitor_pid_evh,monitor);
2182  }
2183 
2184  /*
2185  * Close child ends of pipes.
2186  */
2187  if (monitor->child_recv_fd > -1) {
2188  close(monitor->child_recv_fd);
2189  monitor->child_recv_fd = -1;
2190  }
2191  if (monitor->child_send_fd > -1) {
2192  close(monitor->child_send_fd);
2193  monitor->child_send_fd = -1;
2194  }
2195  if (monitor->p.stdin_c_fd > -1) {
2196  close(monitor->p.stdin_c_fd);
2197  monitor->p.stdin_c_fd = -1;
2198  }
2199  if (monitor->p.stdout_c_fd > -1) {
2200  close(monitor->p.stdout_c_fd);
2201  monitor->p.stdout_c_fd = -1;
2202  }
2203  if (monitor->p.stderr_c_fd > -1) {
2204  close(monitor->p.stderr_c_fd);
2205  monitor->p.stderr_c_fd = -1;
2206  }
2207  }
2208 
2209  return pid;
2210 }
2211 
2212 static int __monitor_error_evh(int errortype,int fd,int fdtype,
2213  struct evloop_fdinfo *error_fdinfo) {
2214  /*
2215  * Basically, we have to check all our FDs, see which one the error
2216  * happened for, then decide what to do!
2217  */
2218  vdebug(5,LA_LIB,LF_MONITOR,"errortype %d fd %d fdtype %d\n",
2219  errortype,fd,fdtype);
2220 
2221  return EVLOOP_HRET_SUCCESS;
2222 }
2223 
2224 int monitor_is_done(struct monitor *monitor) {
2225  if (monitor->live_children < 1 && monitor->live_objs < 1)
2226  return 1;
2227  else
2228  return 0;
2229 }
2230 
2231 int monitor_live_children(struct monitor *monitor) {
2232  int retval;
2233 
2234  pthread_mutex_lock(&monitor->mutex);
2235  retval = monitor->p.pid > -1 ? 1 : 0;
2236  pthread_mutex_unlock(&monitor->mutex);
2237 
2238  return retval;
2239 }
2240 
2241 int monitor_live_objects(struct monitor *monitor) {
2242  int retval;
2243 
2244  pthread_mutex_lock(&monitor->mutex);
2245  retval = monitor->live_objs;
2246  pthread_mutex_unlock(&monitor->mutex);
2247 
2248  return retval;
2249 }
2250 
2251 int monitor_objects(struct monitor *monitor) {
2252  int retval = 0;
2253  GHashTableIter iter;
2254  struct monitor *_monitor;
2255 
2256  pthread_mutex_lock(&monitor_mutex);
2257  pthread_mutex_lock(&monitor->mutex);
2258 
2259  g_hash_table_iter_init(&iter,objid_monitor_tab);
2260  while (g_hash_table_iter_next(&iter,NULL,(gpointer *)&_monitor)) {
2261  if (monitor == _monitor)
2262  ++retval;
2263  }
2264 
2265  pthread_mutex_unlock(&monitor->mutex);
2266  pthread_mutex_unlock(&monitor_mutex);
2267 
2268  return retval;
2269 }
2270 
2271 /*
2272  * Runs the monitor (basically just runs its internal evloop).
2273  */
2274 int monitor_run(struct monitor *monitor) {
2275  int rc;
2276  struct monitor_objtype_ops *ops;
2277  GHashTableIter iter;
2278  gpointer key;
2279  void *tobj;
2280  int tobjid;
2281  int objtype;
2282  struct monitor *_monitor;
2283  int found = 1;
2284  struct evloop_fdinfo *fdinfo = NULL;
2285  int fdtype;
2286  int hrc;
2287  int errno_save = 0;
2288 
2289  if (monitor->mtid == 0) {
2290  vwarn(//5,LA_LIB,LF_MONITOR,
2291  "monitor thread already gone, nothing to do\n");
2292  errno = ESRCH;
2293  return -1;
2294  }
2295 
2296  /*
2297  * If the monitor thread is still running, only that thread can
2298  * run the monitor. Otherwise, another thread can.
2299  */
2300  if (pthread_kill(monitor->mtid,0) == 0
2301  && !pthread_equal(pthread_self(),monitor->mtid)) {
2302  verror("only monitor thread can run!\n");
2303  errno = EPERM;
2304  return -1;
2305  }
2306 
2307  if (monitor_is_done(monitor)) {
2308  vwarn("monitor (0x%lx) is done!\n",monitor->mtid);
2309  return 0;
2310  }
2311 
2312  while (1) {
2313  if (monitor_is_done(monitor)) {
2314  vwarn("monitor (0x%lx) is done!\n",monitor->mtid);
2315  return 0;
2316  }
2317 
2318  hrc = -1;
2319  fdinfo = NULL;
2320 
2321  /*
2322  * XXX: fix this! Race condition, because we cannot call this
2323  * with the main monitor mutex held. This is going to be tricky
2324  * to fix...
2325  */
2326  rc = evloop_handleone(monitor->evloop,0,NULL,&fdinfo,&fdtype,&hrc);
2327 
2328  pthread_mutex_lock(&monitor_mutex);
2329  pthread_mutex_lock(&monitor->mutex);
2330 
2331  if (rc == 0) {
2332  /*
2333  * Each time we handle an event, we need to check the status
2334  * of the monitored child, and/or the monitored objects.
2335  */
2336 
2337  if (monitor->type == MONITOR_TYPE_PROCESS) {
2338  if (monitor->live_children > 0
2339  && monitor->p.pid_waitpipe_fd < 0) {
2341  "monitor (0x%lx) child (%d) finished\n",
2342  monitor->mtid,monitor->p.pid);
2343  monitor->live_children = 0;
2344 
2345  __monitor_lookup_obj(monitor->obj,&objtype,NULL,NULL);
2346  ops = __monitor_lookup_objtype_ops(objtype);
2347 
2348  if (ops && ops->event)
2349  ops->event(monitor,MONITOR_EVENT_CHILD_DIED,
2350  monitor->objid,monitor->obj);
2351  }
2352  else if (monitor->live_children) {
2354  "monitor (0x%lx) child (%d) still running\n",
2355  monitor->mtid,monitor->p.pid);
2356  }
2357  }
2358 
2360  "checking status of monitor (0x%lx) objs\n",monitor->mtid);
2361 
2362  monitor->live_objs = 0;
2363 
2364  g_hash_table_iter_init(&iter,objid_monitor_tab);
2365  while (g_hash_table_iter_next(&iter,&key,(gpointer *)&_monitor)) {
2366  if (monitor != _monitor)
2367  continue;
2368 
2369  tobjid = (int)(uintptr_t)key;
2370 
2371  if (!__monitor_lookup_objid(tobjid,&objtype,&tobj,NULL)) {
2372  verror("could not lookup objid %d to check its status!\n",
2373  tobjid);
2374  }
2375  else {
2376  ops = __monitor_lookup_objtype_ops(objtype);
2377  if (ops->evloop_is_attached)
2378  rc = ops->evloop_is_attached(monitor->evloop,tobj);
2380  "objid %d attached = %d\n",tobjid,rc);
2381  if (rc)
2382  ++monitor->live_objs;
2383 
2384  /*
2385  * XXX: notify no matter what, for now.
2386  */
2387  if (ops->notify)
2388  ops->notify(tobj);
2389  }
2390  }
2391 
2392  if (monitor->live_children < 1 && monitor->live_objs < 1) {
2394  "monitor (0x%lx) has no children nor live objects"
2395  " (%d objects total)\n",
2396  monitor->mtid,monitor->objs);
2397  pthread_mutex_unlock(&monitor_mutex);
2398  pthread_mutex_unlock(&monitor->mutex);
2399 
2400  return 0;
2401  }
2402  else if (evloop_maxsize(monitor->evloop) < 0) {
2403  pthread_mutex_unlock(&monitor_mutex);
2404  pthread_mutex_unlock(&monitor->mutex);
2405 
2406  verror("monitor (0x%lx) has no more FDs in evloop, but has"
2407  " %d children and %d live objs (%d total objs)!\n",
2408  monitor->mtid,monitor->live_children,monitor->live_objs,
2409  monitor->objs);
2410 
2411  errno = EINVAL;
2412 
2413  return -1;
2414  }
2415  else {
2417  "monitor (0x%lx) has %d children and %d live objs"
2418  " (%d total objs); continuing\n",
2419  monitor->mtid,monitor->live_children,monitor->live_objs,
2420  monitor->objs);
2421  pthread_mutex_unlock(&monitor_mutex);
2422  pthread_mutex_unlock(&monitor->mutex);
2423  continue;
2424  }
2425  }
2426 
2427  /*
2428  * XXX: Fatal error -- handle I/O errors of our own, and
2429  * call the fatal handler for the objtype; then free
2430  * ourself.
2431  */
2432  verror("fatal uncaught error from evloop_handleone, cleaning up!\n");
2433  errno_save = errno;
2434 
2435  while (found) {
2436  found = 0;
2437  g_hash_table_iter_init(&iter,objid_monitor_tab);
2438  while (g_hash_table_iter_next(&iter,&key,(gpointer *)&_monitor)) {
2439  if (monitor == _monitor) {
2440  found = 1;
2441 
2442  tobjid = (int)(uintptr_t)key;
2443 
2444  if (!__monitor_lookup_objid(tobjid,&objtype,&tobj,NULL)) {
2445  verror("could not lookup objid %d to deliver fatal error!\n",
2446  tobjid);
2447  }
2448  else {
2449  ops = __monitor_lookup_objtype_ops(objtype);
2450  if (ops->fatal_error)
2452  }
2453 
2454  /* Let the target decide if it should self-terminate! */
2455  __monitor_del_obj(monitor,tobjid,objtype,tobj,obj_monitor_tab);
2456 
2457  g_hash_table_iter_remove(&iter);
2458 
2459  break;
2460  }
2461  }
2462  }
2463 
2464  pthread_mutex_unlock(&monitor_mutex);
2465  pthread_mutex_unlock(&monitor->mutex);
2466 
2467  errno = errno_save;
2468  return -11;
2469  }
2470 
2471  /* Never reached. */
2472  return -1;
2473 }
2474 
2475 static void __monitor_store_msg_obj(struct monitor *monitor,
2476  struct monitor_msg *msg) {
2477  if (!msg->msg_obj)
2478  return;
2479 
2480  g_hash_table_insert(monitor->msg_obj_tab,
2481  (gpointer)(uintptr_t)msg->id,msg->msg_obj);
2482 }
2483 
2484 void monitor_store_msg_obj(struct monitor *monitor,
2485  struct monitor_msg *msg) {
2486  if (!msg->msg_obj)
2487  return;
2488 
2489  pthread_mutex_lock(&monitor->msg_obj_tab_mutex);
2490  monitor_store_msg_obj(monitor,msg);
2491  pthread_mutex_unlock(&monitor->msg_obj_tab_mutex);
2492 }
2493 
2494 static void *monitor_peek_msg_obj(struct monitor *monitor,
2495  struct monitor_msg *msg) {
2496  void *retval;
2497 
2498  pthread_mutex_lock(&monitor->msg_obj_tab_mutex);
2499  retval = (void *)g_hash_table_lookup(monitor->msg_obj_tab,
2500  (gpointer)(uintptr_t)msg->id);
2501  pthread_mutex_unlock(&monitor->msg_obj_tab_mutex);
2502 
2503  return retval;
2504 }
2505 
2506 static void monitor_retrieve_msg_obj(struct monitor *monitor,
2507  struct monitor_msg *msg) {
2508  pthread_mutex_lock(&monitor->msg_obj_tab_mutex);
2509  msg->msg_obj = g_hash_table_lookup(monitor->msg_obj_tab,
2510  (gpointer)(uintptr_t)msg->id);
2511  g_hash_table_remove(monitor->msg_obj_tab,(gpointer)(uintptr_t)msg->id);
2512  pthread_mutex_unlock(&monitor->msg_obj_tab_mutex);
2513 }
2514 
2515 void monitor_msg_free(struct monitor_msg *msg) {
2516  if (msg->msg)
2517  free(msg->msg);
2518  free(msg);
2519 }
2520 
2522  free(msg);
2523 }
2524 
2526  int id,short cmd,short seqno,
2527  int buflen,char *buf,
2528  void *msg_obj) {
2529  struct monitor *monitor = NULL;
2530  struct monitor_msg *msg;
2531  void *obj = NULL;
2532 
2533  if (id == -1) {
2534  if (objid > 0
2535  && !monitor_lookup_objid_lock_monitor(objid,NULL,&obj,&monitor)) {
2536  vwarn("could not find monitor for objid %d to get msg_obj_id!\n",
2537  objid);
2538  }
2539  else {
2540  id = ++monitor->msg_obj_id_counter;
2541  pthread_mutex_unlock(&monitor->mutex);
2542  }
2543  }
2544 
2545  msg = calloc(1,sizeof(*msg));
2546 
2547  msg->objid = objid;
2548 
2549  msg->cmd = cmd;
2550  msg->seqno = seqno;
2551  msg->len = buflen;
2552  msg->msg = buf; //malloc(buflen);
2553  //memcpy(msg->msg,buf,buflen);
2554 
2555  /*
2556  * These do not get emplaced into the state table until send.
2557  */
2558  msg->id = id;
2559  msg->msg_obj = msg_obj;
2560 
2561  if (!msg_obj && objid > 0) {
2562  if (!monitor_lookup_objid(objid,NULL,&obj,&monitor)) {
2564  "could not find obj for objid %d!\n",objid);
2565  }
2566  else
2567  msg->obj = obj;
2568  }
2569 
2570  return msg;
2571 }
2572 
2573 #define __M_SAFE_IO(fn,fns,fd,buf,buflen,frc) { \
2574  char *_p; \
2575  int _left; \
2576  \
2577  _p = (char *)(buf); \
2578  _left = (buflen); \
2579  \
2580  while (_left) { \
2581  (frc) = fn((fd),_p,_left); \
2582  if ((frc) < 0) { \
2583  if (errno == EAGAIN || errno == EWOULDBLOCK) { \
2584  goto errout_wouldblock; \
2585  } \
2586  else if (errno != EINTR) { \
2587  vwarn(fns "(%d,%d): %s\n", \
2588  fd,buflen,strerror(errno)); \
2589  goto errout_fatal; \
2590  } \
2591  else { \
2592  verror(fns "(%d,%d): %s\n", \
2593  fd,buflen,strerror(errno)); \
2594  } \
2595  } \
2596  else if ((frc) == 0) { \
2597  goto errout_wouldblock; \
2598  } \
2599  else { \
2600  _left -= (frc); \
2601  _p += (frc); \
2602  } \
2603  } \
2604  /*vwarn("%d bytes of %d iopd\n",(buflen)-_left,(buflen));*/ \
2605 }
2606 
2607 int monitor_send(struct monitor_msg *msg) {
2608  struct monitor *monitor;
2609  unsigned int rc = 0;
2610  unsigned int len;
2611  int frc = 0;
2612 
2613  /*
2614  * We have to lookup the monitor and hold its lock to make sure
2615  * the monitor thread does not monitor_free() it out from under us!
2616  */
2617  if (!monitor_lookup_objid_lock_monitor(msg->objid,NULL,NULL,&monitor)) {
2618  errno = ESRCH;
2619  return -1;
2620  }
2621 
2622  /*
2623  * Insert the object and release the lock first so receiver does not
2624  * block on it if it reads the msg before the sender releases the
2625  * lock.
2626  */
2627  if (msg->msg_obj)
2628  __monitor_store_msg_obj(monitor,msg);
2629 
2630  len = sizeof(msg->objid) + sizeof(msg->id) \
2631  + sizeof(msg->cmd) + sizeof(msg->seqno) + sizeof(msg->len);
2632  if (msg->len > 0)
2633  len += msg->len;
2634 
2635  /*
2636  * Now send the message.
2637  */
2638  if (monitor->monitor_send_fd < 1) {
2639  if (monitor->type == MONITOR_TYPE_THREAD) {
2640  verror("no way to send to thread %lu!\n",monitor->mtid);
2641  }
2642  else if (monitor->type == MONITOR_TYPE_PROCESS) {
2643  verror("no way to send to process %d!\n",monitor->p.pid);
2644  }
2645  errno = EINVAL;
2646  goto errout;
2647  }
2648 
2649  /* Write the msg objid */
2650  __M_SAFE_IO(write,"write",monitor->monitor_send_fd,
2651  &msg->objid,(int)sizeof(msg->objid),frc);
2652  rc += (int)sizeof(msg->objid);
2653 
2654  /* Write the msg id */
2655  __M_SAFE_IO(write,"write",monitor->monitor_send_fd,
2656  &msg->id,(int)sizeof(msg->id),frc);
2657  rc += (int)sizeof(msg->id);
2658 
2659  /* Write the msg cmd */
2660  __M_SAFE_IO(write,"write",monitor->monitor_send_fd,
2661  &msg->cmd,(int)sizeof(msg->cmd),frc);
2662  rc += (int)sizeof(msg->cmd);
2663 
2664  /* Write the msg seqno */
2665  __M_SAFE_IO(write,"write",monitor->monitor_send_fd,
2666  &msg->seqno,(int)sizeof(msg->seqno),frc);
2667  rc += (int)sizeof(msg->seqno);
2668 
2669  /* Write the msg payload len */
2670  __M_SAFE_IO(write,"write",monitor->monitor_send_fd,
2671  &msg->len,(int)sizeof(msg->len),frc);
2672  rc += (int)sizeof(msg->len);
2673 
2674  if (msg->len > 0) {
2675  /* Write the msg payload, if any */
2676  __M_SAFE_IO(write,"write",monitor->monitor_send_fd,msg->msg,msg->len,frc);
2677  rc += msg->len;
2678  }
2679 
2681  "sent objid(%d) %d %hd:%hd '%s' (%d)\n",
2682  msg->objid,msg->id,msg->cmd,msg->seqno,msg->msg,msg->len);
2683 
2684  pthread_mutex_unlock(&monitor->mutex);
2685  return 0;
2686 
2687  errout_wouldblock:
2688  if (rc < len && (errno == EAGAIN || errno == EWOULDBLOCK)) {
2689  verror("would have blocked after %d of %d bytes (%d)!\n",rc,len,frc);
2690  goto errout;
2691  }
2692 
2693  errout_fatal:
2694  /*
2695  * Error while writing to pipe; may be in bad state; must nuke the
2696  * pipe. We can leave the monitor open, but all communication ends
2697  * here.
2698  *
2699  * Actually, we can't nuke the pipe, because the caller may not be
2700  * the thread monitoring the monitor's evloop -- so we cannot alter
2701  * the evloop.
2702  *
2703  * The only thing we *can* do is close() the pipe FD; do that for
2704  * now and let the evloop handle that normally (it should see an
2705  * error condition too, if it's a real problem?).
2706  */
2707  if (errno == EPIPE) {
2708  close(monitor->monitor_send_fd);
2709  monitor->monitor_send_fd = -1;
2710  }
2711 
2712  errout:
2713  pthread_mutex_unlock(&monitor->mutex);
2714  if (msg->msg_obj)
2715  monitor_retrieve_msg_obj(monitor,msg);
2716  return -1;
2717 }
2718 
2719 struct monitor_msg *monitor_recv(struct monitor *monitor) {
2720  struct monitor_msg *msg = monitor_msg_create(-1,0,0,0,0,NULL,NULL);
2721  int frc = 0;
2722  int rc = 0;
2723  int len;
2724  void *obj;
2725  struct monitor *_monitor = NULL;
2726 
2727  len = sizeof(msg->objid) + sizeof(msg->id) \
2728  + sizeof(msg->cmd) + sizeof(msg->seqno) + sizeof(msg->len);
2729 
2730  /* Read the msg objid */
2731  __M_SAFE_IO(read,"read",monitor->monitor_recv_fd,
2732  &msg->objid,(int)sizeof(msg->objid),frc);
2733  rc += (int)sizeof(msg->objid);
2734 
2735  /* Read the msg id */
2736  __M_SAFE_IO(read,"read",monitor->monitor_recv_fd,
2737  &msg->id,(int)sizeof(msg->id),frc);
2738  rc += (int)sizeof(msg->id);
2739 
2740  /* Read the msg cmd */
2741  __M_SAFE_IO(read,"read",monitor->monitor_recv_fd,&msg->cmd,
2742  (int)sizeof(msg->cmd),frc);
2743  rc += (int)sizeof(msg->cmd);
2744 
2745  /* Read the msg seqno */
2746  __M_SAFE_IO(read,"read",monitor->monitor_recv_fd,&msg->seqno,
2747  (int)sizeof(msg->seqno),frc);
2748  rc += (int)sizeof(msg->seqno);
2749 
2750  /* Read the msg payload len */
2751  __M_SAFE_IO(read,"read",monitor->monitor_recv_fd,
2752  &msg->len,(int)sizeof(msg->len),frc);
2753  rc += (int)sizeof(msg->len);
2754 
2755  if (msg->len > 0)
2756  len += msg->len;
2757 
2758  /* Read the msg payload */
2759  if (msg->len > 0) {
2760  msg->msg = malloc(msg->len);
2761  __M_SAFE_IO(read,"read",monitor->monitor_recv_fd,
2762  msg->msg,msg->len,frc);
2763  rc += msg->len;
2764  }
2765 
2767  " objid(%d) %d %hd:%hd '%s' (%d)\n",
2768  msg->objid,msg->id,msg->cmd,msg->seqno,msg->msg,msg->len);
2769 
2770  /* Don't lock here; the sender holds the lock! */
2771  if (!__monitor_lookup_objid(msg->objid,NULL,&obj,&_monitor)) {
2772  vwarn("could not find obj for objid %d!\n",msg->objid);
2773  msg->obj = NULL;
2774  }
2775  else
2776  msg->obj = obj;
2777 
2778  monitor_retrieve_msg_obj(monitor,msg);
2779 
2780  return msg;
2781 
2782  errout_wouldblock:
2783  if (rc < len && (errno == EAGAIN || errno == EWOULDBLOCK)) {
2784  verror("would have blocked after %d of (at least) %d bytes (%d)!\n",
2785  rc,len,frc);
2786  goto errout_fatal_2;
2787  }
2788 
2789  errout_fatal:
2790  verror("would have blocked after %d of (at least) %d bytes (%d)!\n",
2791  rc,len,frc);
2792  errout_fatal_2:
2793  monitor_msg_free(msg);
2794 
2795  return NULL;
2796 }
2797 
2798 int monitor_child_send(struct monitor_msg *msg,struct monitor *monitor) {
2799  struct monitor *_monitor;
2800  int rc = 0;
2801  int len;
2802  int frc = 0;
2803 
2804  /*
2805  * We have to lookup the monitor and hold its lock to make sure
2806  * the monitor thread does not monitor_free() it out from under us!
2807  */
2808 
2809  if (!monitor_lookup_objid_lock_monitor(msg->objid,NULL,NULL,&_monitor)) {
2811  "could not lookup objid %d; deleted?\n",msg->objid);
2812  _monitor = monitor;
2813  }
2814  else if (_monitor != monitor) {
2815  verror("trying to send msg for objid %d on a different monitor!\n",
2816  msg->objid);
2817  }
2818 
2819  len = sizeof(msg->objid) + sizeof(msg->id) \
2820  + sizeof(msg->cmd) + sizeof(msg->seqno) + sizeof(msg->len);
2821  if (msg->len > 0)
2822  len += msg->len;
2823 
2824  /*
2825  * If this is a process-based monitor, we allow multiple threads in
2826  * the child! So we have to lock to ensure our sends are
2827  * synchronous.
2828  *
2829  * Insert the object and release the lock first so receiver does not
2830  * block on it if it reads the msg before the sender releases the
2831  * lock.
2832  */
2833  if (msg->msg_obj && _monitor->type == MONITOR_TYPE_PROCESS)
2834  __monitor_store_msg_obj(_monitor,msg);
2835 
2836  /*
2837  * Now send the message. No locking FOR THREADS because only one caller.
2838  */
2839  if (_monitor->child_send_fd < 1) {
2840  if (_monitor->type == MONITOR_TYPE_THREAD) {
2841  verror("no way to send from monitor thread!\n");
2842  }
2843  else if (_monitor->type == MONITOR_TYPE_PROCESS) {
2844  verror("no way to send from monitored process!\n");
2845  }
2846  errno = EINVAL;
2847  goto errout_fatal;
2848  }
2849 
2850  /* Write the msg objid */
2851  __M_SAFE_IO(write,"write",_monitor->child_send_fd,
2852  &msg->objid,(int)sizeof(msg->objid),frc);
2853  rc += (int)sizeof(msg->objid);
2854 
2855  /* Write the msg id */
2856  __M_SAFE_IO(write,"write",_monitor->child_send_fd,
2857  &msg->id,(int)sizeof(msg->id),frc);
2858  rc += (int)sizeof(msg->id);
2859 
2860  /* Write the msg cmd */
2861  __M_SAFE_IO(write,"write",_monitor->child_send_fd,
2862  &msg->cmd,(int)sizeof(msg->cmd),frc);
2863  rc += (int)sizeof(msg->cmd);
2864 
2865  /* Write the msg seqno */
2866  __M_SAFE_IO(write,"write",_monitor->child_send_fd,
2867  &msg->seqno,(int)sizeof(msg->seqno),frc);
2868  rc += (int)sizeof(msg->seqno);
2869 
2870  /* Write the msg payload len */
2871  __M_SAFE_IO(write,"write",_monitor->child_send_fd,
2872  &msg->len,(int)sizeof(msg->len),frc);
2873  rc += (int)sizeof(msg->len);
2874 
2875  if (msg->len > 0) {
2876  /* Write the msg payload, if any */
2877  __M_SAFE_IO(write,"write",_monitor->child_send_fd,msg->msg,msg->len,frc);
2878  rc += msg->len;
2879  }
2880 
2882  " objid(%d) %d %hd:%hd '%s' (%d)\n",
2883  msg->objid,msg->id,msg->cmd,msg->seqno,msg->msg,msg->len);
2884 
2885  pthread_mutex_unlock(&_monitor->mutex);
2886  return 0;
2887 
2888  errout_wouldblock:
2889  if (rc < len && (errno == EAGAIN || errno == EWOULDBLOCK)) {
2890  verror("would have blocked after %d of %d bytes (BUG) (%d)!\n",rc,len,frc);
2891  goto errout_fatal;
2892  }
2893 
2894  errout_fatal:
2895  /*
2896  * Error while writing to pipe; may be in bad state; must nuke the
2897  * pipe. We can leave the monitor open, but all communication ends
2898  * here.
2899  *
2900  * Actually, we can't nuke the pipe, because the caller may not be
2901  * the thread monitoring the monitor's evloop -- so we cannot alter
2902  * the evloop. The only thing we *could* do is close() the pipe
2903  * FDs, but for now let's not, and let's let the evloop handle that
2904  * normally (it should see an error condition too, if it's a real
2905  * problem?).
2906  */
2907  verror("error after %d of %d bytes: %s (%d)!\n",rc,len,strerror(errno),frc);
2908  pthread_mutex_unlock(&monitor->mutex);
2909  if (msg->msg_obj)
2910  monitor_retrieve_msg_obj(monitor,msg);
2911  return -1;
2912 }
2913 
2914 struct monitor_msg *monitor_child_recv(struct monitor *monitor) {
2915  struct monitor_msg *msg = monitor_msg_create(-1,0,0,0,0,NULL,NULL);
2916  int frc = 0;
2917  int rc = 0;
2918  int len;
2919  void *obj;
2920  struct monitor *_monitor = NULL;
2921 
2922  len = sizeof(msg->objid) + sizeof(msg->id) \
2923  + sizeof(msg->cmd) + sizeof(msg->seqno) + sizeof(msg->len);
2924 
2925  /* Read the msg objid */
2926  __M_SAFE_IO(read,"read",monitor->child_recv_fd,
2927  &msg->objid,(int)sizeof(msg->objid),frc);
2928  rc += (int)sizeof(msg->objid);
2929 
2930  /* Read the msg id */
2931  __M_SAFE_IO(read,"read",monitor->child_recv_fd,
2932  &msg->id,(int)sizeof(msg->id),frc);
2933  rc += (int)sizeof(msg->id);
2934 
2935  /* Read the msg cmd */
2936  __M_SAFE_IO(read,"read",monitor->child_recv_fd,&msg->cmd,
2937  (int)sizeof(msg->cmd),frc);
2938  rc += (int)sizeof(msg->cmd);
2939 
2940  /* Read the msg seqno */
2941  __M_SAFE_IO(read,"read",monitor->child_recv_fd,&msg->seqno,
2942  (int)sizeof(msg->seqno),frc);
2943  rc += (int)sizeof(msg->seqno);
2944 
2945  /* Read the msg payload len */
2946  __M_SAFE_IO(read,"read",monitor->child_recv_fd,
2947  &msg->len,(int)sizeof(msg->len),frc);
2948  rc += (int)sizeof(msg->len);
2949 
2950  if (msg->len > 0)
2951  len += msg->len;
2952 
2954  " objid(%d) %d %hd:%hd '%s' (%d)\n",
2955  msg->objid,msg->id,msg->cmd,msg->seqno,msg->msg,msg->len);
2956 
2957  /* Read the msg payload */
2958  if (msg->len > 0) {
2959  msg->msg = malloc(msg->len);
2960  __M_SAFE_IO(read,"read",monitor->child_recv_fd,
2961  msg->msg,(int)msg->len,frc);
2962  rc += msg->len;
2963  }
2964 
2966  " objid(%d) %d %hd:%hd '%s' (%d)\n",
2967  msg->objid,msg->id,msg->cmd,msg->seqno,msg->msg,msg->len);
2968 
2969  /*
2970  * Don't lock here; the sender holds the lock if this is a threaded
2971  * monitor!
2972  */
2973  if (!__monitor_lookup_objid(msg->objid,NULL,&obj,&_monitor)) {
2974  vwarn("could not find obj for objid %d!\n",msg->objid);
2975  msg->obj = NULL;
2976  }
2977  else
2978  msg->obj = obj;
2979 
2980  if (rc != len)
2981  vwarn("received msg len only %d (should be %d) (%d)\n",rc,len,frc);
2982 
2983  monitor_retrieve_msg_obj(monitor,msg);
2984 
2985  return msg;
2986 
2987  errout_wouldblock:
2988  if (rc < len && (errno == EAGAIN || errno == EWOULDBLOCK)) {
2989  verror("would have blocked after %d of %d bytes (BUG) (%d)!\n",rc,len,frc);
2990  goto errout_fatal_2;
2991  }
2992 
2993  errout_fatal:
2994  verror("error after %d of %d bytes: %s (%d)!\n",rc,len,strerror(errno),frc);
2995  errout_fatal_2:
2996  monitor_msg_free(msg);
2997 
2998  return NULL;
2999 }
int monitor_lock_objtype(int objtype)
Definition: monitor.c:243
void * xhstate
Definition: evloop.h:90
monitor_type_t
Definition: monitor.h:32
int monitor_is_done(struct monitor *monitor)
Definition: monitor.c:2224
int monitor_objects(struct monitor *monitor)
Definition: monitor.c:2251
int waitpipe_add(int pid)
Definition: waitpipe.c:184
int monitor_get_unique_objid(void)
Definition: monitor.c:161
int stdout_log_fd
Definition: monitor.h:310
#define EVLOOP_HRET_REMOVEALLTYPES
Definition: evloop.h:38
#define vwarnopt(level, area, flags, format,...)
Definition: log.h:37
int(* monitor_stdio_callback_t)(int fd, char *buf, int len, void *state)
Definition: monitor.h:82
int live_children
Definition: monitor.h:191
struct monitor_msg * monitor_recv(struct monitor *monitor)
Definition: monitor.c:2719
int monitor_run(struct monitor *monitor)
Definition: monitor.c:2274
int waitpipe_init_auto(void(*alt_handler)(int, siginfo_t *, void *))
Definition: waitpipe.c:140
char * stderr_logfile
Definition: monitor.h:319
void * obj
Definition: monitor.h:244
void evloop_free(struct evloop *evloop)
Definition: evloop.c:652
int __monitor_unlock_objtype(int objtype)
Definition: monitor.c:253
int pid
Definition: monitor.h:294
int(* close)(struct monitor *monitor, void *obj, void *objstate, int kill, int kill_sig)
Definition: monitor.h:108
int stdin_c_fd
Definition: monitor.h:302
int monitor_send_fd
Definition: monitor.h:266
void * obj
Definition: monitor.h:358
void * rhstate
Definition: evloop.h:86
GHashTable * msg_obj_tab
Definition: monitor.h:221
struct array_list * monitor_list_objs_by_objtype_lock_objtype(int objtype, int include_null)
Definition: monitor.c:315
void monitor_fini(void)
Definition: monitor.c:127
int monitor_lookup_obj_lock_monitor(void *obj, int *objtype, int *objid, struct monitor **monitor)
Definition: monitor.c:456
int __safe_write(int fd, char *buf, int count)
Definition: monitor.c:1191
static uint64_t unsigned int i
char ** environ
void * stdout_callback_state
Definition: monitor.h:313
int objid
Definition: monitor.h:335
struct monitor * monitor
int monitor_setup_stderr(struct monitor *monitor, int maxbufsiz, char *stderr_logfile, monitor_stdio_callback_t stderr_callback, void *callback_state)
Definition: monitor.c:1897
char * msg
Definition: monitor.h:352
int monitor_setup_stdin(struct monitor *monitor, char *stdin_buf, int stdin_buflen)
Definition: monitor.c:1817
void * stdin_callback_state
Definition: monitor.h:325
int monitor_lookup_obj(void *obj, int *objtype, int *objid, struct monitor **monitor)
Definition: monitor.c:444
int monitor_live_objects(struct monitor *monitor)
Definition: monitor.c:2241
int stdout_m_fd
Definition: monitor.h:307
int waitpipe_is_initialized(void)
Definition: waitpipe.c:117
int(* evloop_is_attached)(struct evloop *evloop, void *obj)
Definition: monitor.h:121
int monitor_unlock_objtype(int objtype)
Definition: monitor.c:265
int(* fatal_error)(monitor_error_t error, void *obj)
Definition: monitor.h:144
int stdin_left
Definition: monitor.h:304
int evloop_handleone(struct evloop *evloop, evloop_flags_t flags, struct timeval *timeout, struct evloop_fdinfo **handled_fdinfo, int *handled_fdtype, int *handled_hrc)
Definition: evloop.c:434
int monitor_child_send(struct monitor_msg *msg, struct monitor *monitor)
Definition: monitor.c:2798
struct evloop * evloop
Definition: monitor.h:256
struct monitor_msg * monitor_msg_create(int objid, int id, short cmd, short seqno, int buflen, char *buf, void *msg_obj)
Definition: monitor.c:2525
monitor_type_t type
Definition: monitor.h:175
int monitor_flags_t
Definition: monitor.h:52
int(* event)(struct monitor *monitor, monitor_event_t event, int objid, void *obj)
Definition: monitor.h:145
int monitor_close_obj(struct monitor *monitor, void *obj, int kill, int kill_sig)
Definition: monitor.c:622
int monitor_del_obj(struct monitor *monitor, void *obj)
Definition: monitor.c:763
int(* evloop_detach)(struct evloop *evloop, void *obj)
Definition: monitor.h:99
#define verror(format,...)
Definition: log.h:30
#define EVLOOP_HRET_REMOVETYPE
Definition: evloop.h:37
#define MONITOR_CHILD_RECV_FD_ENVVAR
Definition: monitor.h:77
int stdin_bufsiz
Definition: monitor.h:305
int stdin_m_fd
Definition: monitor.h:301
#define EVLOOP_HRET_DONE_SUCCESS
Definition: evloop.h:39
int monitor_can_attach_bidi(void)
Definition: monitor.c:1609
int objid
Definition: monitor.h:243
#define vwarn(format,...)
Definition: log.h:33
void free(void *ptr)
Definition: debugserver.c:207
int(* fini)(struct monitor *monitor, void *obj, void *objstate)
Definition: monitor.h:116
#define MONITOR_OBJID_ENVVAR
Definition: monitor.h:79
#define MONITOR_CHILD_SEND_FD_ENVVAR
Definition: monitor.h:78
void monitor_msg_free(struct monitor_msg *msg)
Definition: monitor.c:2515
Definition: log.h:68
int waitpipe_remove(int pid)
Definition: waitpipe.c:284
int monitor_lookup_objid_lock_objtype(int objid, int objtype, void **obj, struct monitor **monitor)
Definition: monitor.c:350
int stderr_m_fd
Definition: monitor.h:315
int __monitor_child_recv_evh(int fd, int fdtype, void *state)
Definition: monitor.c:1138
short cmd
Definition: monitor.h:349
int __monitor_send_stdin_evh(int fd, int fdtype, void *state)
Definition: monitor.c:1762
int(* child_recv_msg)(struct monitor *monitor, struct monitor_msg *msg)
Definition: monitor.h:133
monitor_stdio_callback_t stderr_callback
Definition: monitor.h:320
pthread_mutex_t mutex
Definition: monitor.h:186
int stderr_log_fd
Definition: monitor.h:318
int child_recv_fd
Definition: monitor.h:267
#define EVLOOP_FDTYPE_X
Definition: evloop.h:32
pthread_mutex_t msg_obj_tab_mutex
Definition: monitor.h:231
int monitor_recv_fd
Definition: monitor.h:285
int len
Definition: dumptarget.c:52
pthread_t mtid
Definition: monitor.h:180
int monitor_add_obj(struct monitor *monitor, int objid, int objtype, void *obj, void *objstate)
Definition: monitor.c:554
int objs
Definition: monitor.h:201
int live_objs
Definition: monitor.h:196
void monitor_msg_free_save_buffer(struct monitor_msg *msg)
Definition: monitor.c:2521
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
int evloop_set_fd(struct evloop *evloop, int fd, int fdtype, evloop_handler_t handler, void *state)
Definition: evloop.c:48
int child_send_fd
Definition: monitor.h:284
int(* recv_msg)(struct monitor *monitor, struct monitor_msg *msg)
Definition: monitor.h:134
short seqno
Definition: monitor.h:350
struct monitor * monitor_attach(monitor_type_t type, monitor_flags_t flags, int objtype, void *obj, void *objstate, evloop_handler_t custom_child_recv_evh, monitor_stdio_callback_t stdin_callback, void *callback_state)
Definition: monitor.c:1616
int monitor_add_primary_obj(struct monitor *monitor, int objid, int objtype, void *obj, void *objstate)
Definition: monitor.c:1576
int evloop_maxsize(struct evloop *evloop)
Definition: evloop.c:191
void * whstate
Definition: evloop.h:88
int monitor_close_objid(struct monitor *monitor, int objid, int kill, int kill_sig)
Definition: monitor.c:648
#define vdebugc(devel, areas, flags, format,...)
Definition: log.h:303
int monitor_live_children(struct monitor *monitor)
Definition: monitor.c:2231
char * stdout_logfile
Definition: monitor.h:311
struct monitor::@11 p
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
int unlink(const char *pathname)
Definition: qemuhacks.c:134
int monitor_shutdown(struct monitor *monitor)
Definition: monitor.c:947
struct evloop * evloop_create(evloop_error_handler_t ehandler)
Definition: evloop.c:33
#define EVLOOP_HRET_SUCCESS
Definition: evloop.h:36
monitor_stdio_callback_t stdout_callback
Definition: monitor.h:312
struct array_list * monitor_list_objids_by_objtype_lock_objtype(int objtype, int include_null)
Definition: monitor.c:279
int pid_waitpipe_fd
Definition: monitor.h:296
int monitor_can_attach(void)
Definition: monitor.c:1603
int monitor_lookup_objid(int objid, int *objtype, void **obj, struct monitor **monitor)
Definition: monitor.c:219
int monitor_unlock_objtype_unsafe(int objtype)
Definition: monitor.c:275
int monitor_lookup_objid_lock_monitor(int objid, int *objtype, void **obj, struct monitor **monitor)
Definition: monitor.c:400
monitor_flags_t flags
Definition: monitor.h:177
int monitor_spawn(struct monitor *monitor, char *filename, char *const argv[], char *const envp[], char *dir)
Definition: monitor.c:2002
int msg_obj_id_counter
Definition: monitor.h:237
#define EVLOOP_FDTYPE_W
Definition: evloop.h:31
int(* evloop_attach)(struct evloop *evloop, void *obj)
Definition: monitor.h:93
struct monitor * monitor_create_custom(monitor_type_t type, monitor_flags_t flags, int objid, int objtype, void *obj, void *objstate, evloop_handler_t custom_recv_evh, evloop_handler_t custom_child_recv_evh)
Definition: monitor.c:1411
int status
Definition: monitor.h:295
#define __M_SAFE_IO(fn, fns, fd, buf, buflen, frc)
Definition: monitor.c:2573
#define EVLOOP_FDTYPE_R
Definition: evloop.h:30
void * stderr_callback_state
Definition: monitor.h:321
struct monitor * monitor_create(monitor_type_t type, monitor_flags_t flags, int objid, int objtype, void *obj, void *objstate)
Definition: monitor.c:1594
int stdout_c_fd
Definition: monitor.h:308
#define EVLOOP_HRET_BADERROR
Definition: evloop.h:34
int __monitor_lock_objtype(int objtype)
Definition: monitor.c:231
char * stdin_buf
Definition: monitor.h:303
int monitor_send(struct monitor_msg *msg)
Definition: monitor.c:2607
void * malloc(size_t size)
Definition: debugserver.c:214
int(* notify)(void *obj)
Definition: monitor.h:156
int monitor_del_objid(struct monitor *monitor, int objid)
Definition: monitor.c:788
int __monitor_add_primary_obj(struct monitor *monitor, int objid, int objtype, void *obj, void *objstate)
Definition: monitor.c:1559
int stderr_c_fd
Definition: monitor.h:316
int vdebug_is_on(int level, log_areas_t areas, log_flags_t flags)
Definition: log.c:335
monitor_stdio_callback_t stdin_callback
Definition: monitor.h:324
void monitor_init(void)
Definition: monitor.c:93
int monitor_setup_stdout(struct monitor *monitor, int maxbufsiz, char *stdout_logfile, monitor_stdio_callback_t stdout_callback, void *callback_state)
Definition: monitor.c:1847
int monitor_destroy(struct monitor *monitor)
Definition: monitor.c:1039
int monitor_register_objtype(int objtype, struct monitor_objtype_ops *ops, pthread_mutex_t *mutex)
Definition: monitor.c:1052
int(* evloop_handler_t)(int fd, int fdtype, void *state)
Definition: evloop.h:62
void * msg_obj
Definition: monitor.h:364
void monitor_store_msg_obj(struct monitor *monitor, struct monitor_msg *msg)
Definition: monitor.c:2484
int __monitor_recv_evh(int fd, int fdtype, void *state)
Definition: monitor.c:1077
int monitor_lookup_objid_lock_objtype_and_monitor(int objid, int objtype, void **obj, struct monitor **monitor)
Definition: monitor.c:372
struct monitor_msg * monitor_child_recv(struct monitor *monitor)
Definition: monitor.c:2914