c9cb777709dab0d84ffffebe26352fcfdfbde563
[lttng-ust.git] / libust / lttng-ust-comm.c
1 /*
2 * lttng-ust-comm.c
3 *
4 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
5 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; only
10 * version 2.1 of the License.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <ust/lttng-ust-abi.h>
27 #include <lttng-ust-comm.h>
28 #include <ust/usterr-signal-safe.h>
29 #include <pthread.h>
30
31 /* Socket from app (connect) to session daemon (listen) for communication */
32 static char global_apps_sock_path[PATH_MAX] = DEFAULT_GLOBAL_APPS_UNIX_SOCK;
33 static pthread_t global_ust_listener;
34
35 /* TODO: allow global_apps_sock_path override */
36
37 static char local_apps_sock_path[PATH_MAX];
38 static pthread_t local_ust_listener;
39
40 static
41 int setup_local_apps_socket(void)
42 {
43 const char *home_dir;
44
45 home_dir = (const char *) getenv("HOME");
46 if (!home_dir)
47 return -ENOENT;
48 snprintf(local_apps_sock_path, PATH_MAX,
49 DEFAULT_HOME_APPS_UNIX_SOCK, home_dir);
50 return 0;
51 }
52
53 static
54 int register_app_to_sessiond(int socket)
55 {
56 ssize_t ret;
57 struct {
58 uint32_t major;
59 uint32_t minor;
60 pid_t pid;
61 uid_t uid;
62 } reg_msg;
63
64 reg_msg.major = LTTNG_UST_COMM_VERSION_MAJOR;
65 reg_msg.minor = LTTNG_UST_COMM_VERSION_MINOR;
66 reg_msg.pid = getpid();
67 reg_msg.uid = getuid();
68
69 ret = lttcomm_send_unix_sock(socket, &reg_msg, sizeof(reg_msg));
70 if (ret >= 0 && ret != sizeof(reg_msg))
71 return -EIO;
72 return ret;
73 }
74
75
76 static
77 int handle_message(int sock, struct lttcomm_ust_msg *lum)
78 {
79 ssize_t len;
80 int ret;
81
82 switch (lum->cmd_type) {
83 case UST_CREATE_SESSION:
84 {
85 struct lttcomm_ust_reply lur;
86
87 DBG("Handling create session message");
88 memset(&lur, 0, sizeof(lur));
89 lur.cmd_type = UST_CREATE_SESSION;
90
91 /* ... */
92 ret = 0;
93
94 if (!ret)
95 lur.ret_code = LTTCOMM_OK;
96 else
97 lur.ret_code = LTTCOMM_SESSION_FAIL;
98 lur.ret_val = 42;
99 len = lttcomm_send_unix_sock(sock, &lur, sizeof(lur));
100 switch (len) {
101 case sizeof(lur):
102 printf("message successfully sent\n");
103 break;
104 case -1:
105 if (errno == ECONNRESET) {
106 printf("remote end closed connection\n");
107 return 0;
108 }
109 return -1;
110 default:
111 printf("incorrect message size: %zd\n", len);
112 return -1;
113 }
114 break;
115 }
116 default:
117 ERR("Unimplemented command %d", (int) lum->cmd_type);
118 return -1;
119 }
120 return 0;
121 }
122
123 static
124 void *ust_listener_thread(void *arg)
125 {
126 const char *sock_path = (const char *) arg;
127 int sock;
128 int ret;
129
130 /* Restart trying to connect to the session daemon */
131 restart:
132
133 /* Check for sessiond availability with pipe TODO */
134
135 /* Register */
136 ret = lttcomm_connect_unix_sock(sock_path);
137 if (ret < 0) {
138 ERR("Error connecting to global apps socket");
139 }
140 sock = ret;
141 ret = register_app_to_sessiond(sock);
142 if (ret < 0) {
143 ERR("Error registering app to local apps socket");
144 sleep(5);
145 goto restart;
146 }
147 for (;;) {
148 ssize_t len;
149 struct lttcomm_ust_msg lum;
150
151 /* Receive session handle */
152 len = lttcomm_recv_unix_sock(sock, &lum, sizeof(lum));
153 switch (len) {
154 case 0: /* orderly shutdown */
155 DBG("ltt-sessiond has performed an orderly shutdown\n");
156 goto end;
157 case sizeof(lum):
158 DBG("message received\n");
159 ret = handle_message(sock, &lum);
160 if (ret) {
161 ERR("Error handling message\n");
162 }
163 continue;
164 case -1:
165 if (errno == ECONNRESET) {
166 ERR("remote end closed connection\n");
167 goto end;
168 }
169 goto end;
170 default:
171 ERR("incorrect message size: %zd\n", len);
172 continue;
173 }
174
175 }
176 end:
177 ret = close(sock);
178 if (ret) {
179 ERR("Error closing local apps socket");
180 }
181 goto restart; /* try to reconnect */
182 return NULL;
183 }
184
185
186 /*
187 * sessiond monitoring thread: monitor presence of global and per-user
188 * sessiond by polling the application common named pipe.
189 */
190 /* TODO */
191
192 void __attribute__((constructor)) lttng_ust_comm_init(void)
193 {
194 int ret;
195
196 init_usterr();
197
198 /* Connect to the per-user (local) sessiond apps socket */
199 ret = setup_local_apps_socket();
200 if (ret) {
201 ERR("Error setting up to local apps socket");
202 }
203 #if 0
204 ret = pthread_create(&global_ust_listener, NULL,
205 ust_listener_thread, global_apps_sock_path);
206 #endif //0
207 ret = pthread_create(&local_ust_listener, NULL,
208 ust_listener_thread, local_apps_sock_path);
209 }
210
211 void __attribute__((destructor)) lttng_ust_comm_exit(void)
212 {
213 int ret;
214
215 /*
216 * Using pthread_cancel here because:
217 * A) we don't want to hang application teardown.
218 * B) the thread is not allocating any resource.
219 */
220 ret = pthread_cancel(global_ust_listener);
221 if (ret) {
222 ERR("Error cancelling global ust listener thread");
223 }
224 ret = pthread_cancel(local_ust_listener);
225 if (ret) {
226 ERR("Error cancelling local ust listener thread");
227 }
228 lttng_ust_abi_exit();
229 }
This page took 0.042368 seconds and 4 git commands to generate.