Convert call-handling syscalls to capabilities
[helenos.git] / uspace / srv / taskmon / taskmon.c
blob60d3b7a4562ca1ffb93869c346d72748960a9f57
1 /*
2 * Copyright (c) 2013 Jiri Svoboda
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 /** @addtogroup taskmon
30 * @brief
31 * @{
33 /**
34 * @file
37 #include <stdio.h>
38 #include <async.h>
39 #include <ipc/services.h>
40 #include <task.h>
41 #include <ipc/corecfg.h>
42 #include <loc.h>
43 #include <macros.h>
44 #include <errno.h>
45 #include <str_error.h>
47 #define NAME "taskmon"
49 static bool write_core_files;
51 static void corecfg_client_conn(ipc_callid_t , ipc_call_t *, void *);
53 static void fault_event(ipc_call_t *call, void *arg)
55 const char *fname;
56 char *s_taskid;
57 char *dump_fname;
58 int rc;
60 task_id_t taskid;
61 uintptr_t thread;
63 taskid = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
64 thread = IPC_GET_ARG3(*call);
66 if (asprintf(&s_taskid, "%" PRIu64, taskid) < 0) {
67 printf("Memory allocation failed.\n");
68 return;
71 printf(NAME ": Task %" PRIu64 " fault in thread %p.\n", taskid,
72 (void *) thread);
74 fname = "/app/taskdump";
76 if (write_core_files) {
77 if (asprintf(&dump_fname, "/data/core%" PRIu64, taskid) < 0) {
78 printf("Memory allocation failed.\n");
79 return;
82 printf(NAME ": Executing %s -c %s -t %s\n", fname, dump_fname, s_taskid);
83 rc = task_spawnl(NULL, NULL, fname, fname, "-c", dump_fname, "-t", s_taskid,
84 NULL);
85 } else {
86 printf(NAME ": Executing %s -t %s\n", fname, s_taskid);
87 rc = task_spawnl(NULL, NULL, fname, fname, "-t", s_taskid, NULL);
90 if (rc != EOK) {
91 printf("%s: Error spawning %s (%s).\n", NAME, fname,
92 str_error(rc));
96 static void corecfg_get_enable_srv(ipc_callid_t iid, ipc_call_t *icall)
98 async_answer_1(iid, EOK, write_core_files);
101 static void corecfg_set_enable_srv(ipc_callid_t iid, ipc_call_t *icall)
103 write_core_files = IPC_GET_ARG1(*icall);
104 async_answer_0(iid, EOK);
107 static void corecfg_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
109 /* Accept the connection */
110 async_answer_0(iid, EOK);
112 while (true) {
113 ipc_call_t call;
114 ipc_callid_t callid = async_get_call(&call);
115 sysarg_t method = IPC_GET_IMETHOD(call);
117 if (!method) {
118 /* The other side has hung up */
119 async_answer_0(callid, EOK);
120 return;
123 switch (method) {
124 case CORECFG_GET_ENABLE:
125 corecfg_get_enable_srv(callid, &call);
126 break;
127 case CORECFG_SET_ENABLE:
128 corecfg_set_enable_srv(callid, &call);
129 break;
134 int main(int argc, char *argv[])
136 printf("%s: Task Monitoring Service\n", NAME);
138 #ifdef CONFIG_WRITE_CORE_FILES
139 write_core_files = true;
140 #else
141 write_core_files = false;
142 #endif
143 if (async_event_subscribe(EVENT_FAULT, fault_event, NULL) != EOK) {
144 printf("%s: Error registering fault notifications.\n", NAME);
145 return -1;
148 async_set_fallback_port_handler(corecfg_client_conn, NULL);
150 int rc = loc_server_register(NAME);
151 if (rc != EOK) {
152 printf("%s: Failed registering server (%d).\n",
153 NAME, rc);
154 return -1;
157 service_id_t sid;
158 rc = loc_service_register(SERVICE_NAME_CORECFG, &sid);
159 if (rc != EOK) {
160 printf("%s: Failed registering service (%d).\n",
161 NAME, rc);
162 return -1;
165 task_retval(0);
166 async_manager();
168 return 0;
171 /** @}