| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: rumpclient.c,v 1.53 2013/01/17 16:29:44 pooka Exp $ */ | | 1 | /* $NetBSD: rumpclient.c,v 1.54 2013/01/17 20:47:44 pooka Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved. | | 4 | * Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
| @@ -38,45 +38,43 @@ | | | @@ -38,45 +38,43 @@ |
38 | * notifications but defer their handling to a stage where we do not | | 38 | * notifications but defer their handling to a stage where we do not |
39 | * hold the communication lock. Taking a signal while holding on to | | 39 | * hold the communication lock. Taking a signal while holding on to |
40 | * that lock may cause a deadlock. Therefore, block signals throughout | | 40 | * that lock may cause a deadlock. Therefore, block signals throughout |
41 | * the RPC when using poll. This unfortunately means that the normal | | 41 | * the RPC when using poll. This unfortunately means that the normal |
42 | * SIGINT way of stopping a process while it is undergoing rump kernel | | 42 | * SIGINT way of stopping a process while it is undergoing rump kernel |
43 | * RPC will not work. If anyone know which Linux system call handles | | 43 | * RPC will not work. If anyone know which Linux system call handles |
44 | * the above scenario correctly, I'm all ears. | | 44 | * the above scenario correctly, I'm all ears. |
45 | */ | | 45 | */ |
46 | | | 46 | |
47 | #ifdef __NetBSD__ | | 47 | #ifdef __NetBSD__ |
48 | #define USE_KQUEUE | | 48 | #define USE_KQUEUE |
49 | #endif | | 49 | #endif |
50 | | | 50 | |
51 | #include <sys/cdefs.h> | | 51 | __RCSID("$NetBSD: rumpclient.c,v 1.54 2013/01/17 20:47:44 pooka Exp $"); |
52 | __RCSID("$NetBSD: rumpclient.c,v 1.53 2013/01/17 16:29:44 pooka Exp $"); | | | |
53 | | | 52 | |
54 | #include <sys/param.h> | | 53 | #include <sys/param.h> |
55 | #include <sys/mman.h> | | 54 | #include <sys/mman.h> |
56 | #include <sys/socket.h> | | 55 | #include <sys/socket.h> |
57 | #include <sys/time.h> | | 56 | #include <sys/time.h> |
58 | | | 57 | |
59 | #ifdef USE_KQUEUE | | 58 | #ifdef USE_KQUEUE |
60 | #include <sys/event.h> | | 59 | #include <sys/event.h> |
61 | #endif | | 60 | #endif |
62 | | | 61 | |
63 | #include <arpa/inet.h> | | 62 | #include <arpa/inet.h> |
64 | #include <netinet/in.h> | | 63 | #include <netinet/in.h> |
65 | #include <netinet/tcp.h> | | 64 | #include <netinet/tcp.h> |
66 | | | 65 | |
67 | #include <assert.h> | | 66 | #include <assert.h> |
68 | #include <dlfcn.h> | | 67 | #include <dlfcn.h> |
69 | #include <err.h> | | | |
70 | #include <errno.h> | | 68 | #include <errno.h> |
71 | #include <fcntl.h> | | 69 | #include <fcntl.h> |
72 | #include <poll.h> | | 70 | #include <poll.h> |
73 | #include <pthread.h> | | 71 | #include <pthread.h> |
74 | #include <signal.h> | | 72 | #include <signal.h> |
75 | #include <stdarg.h> | | 73 | #include <stdarg.h> |
76 | #include <stdbool.h> | | 74 | #include <stdbool.h> |
77 | #include <stdio.h> | | 75 | #include <stdio.h> |
78 | #include <stdlib.h> | | 76 | #include <stdlib.h> |
79 | #include <string.h> | | 77 | #include <string.h> |
80 | #include <unistd.h> | | 78 | #include <unistd.h> |
81 | | | 79 | |
82 | #include <rump/rumpclient.h> | | 80 | #include <rump/rumpclient.h> |
| @@ -149,31 +147,33 @@ send_with_recon(struct spclient *spc, st | | | @@ -149,31 +147,33 @@ send_with_recon(struct spclient *spc, st |
149 | rv = ENOTCONN; | | 147 | rv = ENOTCONN; |
150 | break; | | 148 | break; |
151 | } | | 149 | } |
152 | fprintf(stderr, "rump_sp: connection to " | | 150 | fprintf(stderr, "rump_sp: connection to " |
153 | "kernel lost, trying to reconnect ...\n"); | | 151 | "kernel lost, trying to reconnect ...\n"); |
154 | } else if (time(NULL) - prevreconmsg > 120) { | | 152 | } else if (time(NULL) - prevreconmsg > 120) { |
155 | fprintf(stderr, "rump_sp: still trying to " | | 153 | fprintf(stderr, "rump_sp: still trying to " |
156 | "reconnect ...\n"); | | 154 | "reconnect ...\n"); |
157 | prevreconmsg = time(NULL); | | 155 | prevreconmsg = time(NULL); |
158 | } | | 156 | } |
159 | | | 157 | |
160 | /* check that we aren't over the limit */ | | 158 | /* check that we aren't over the limit */ |
161 | if (retrytimo > 0) { | | 159 | if (retrytimo > 0) { |
162 | struct timeval tmp; | | 160 | time_t tdiff; |
163 | | | 161 | |
164 | gettimeofday(&curtime, NULL); | | 162 | gettimeofday(&curtime, NULL); |
165 | timersub(&curtime, &starttime, &tmp); | | 163 | tdiff = curtime.tv_sec - starttime.tv_sec; |
166 | if (tmp.tv_sec >= retrytimo) { | | 164 | if (starttime.tv_usec > curtime.tv_usec) |
| | | 165 | tdiff--; |
| | | 166 | if (tdiff >= retrytimo) { |
167 | fprintf(stderr, "rump_sp: reconnect " | | 167 | fprintf(stderr, "rump_sp: reconnect " |
168 | "failed, %lld second timeout\n", | | 168 | "failed, %lld second timeout\n", |
169 | (long long)retrytimo); | | 169 | (long long)retrytimo); |
170 | return ENOTCONN; | | 170 | return ENOTCONN; |
171 | } | | 171 | } |
172 | } | | 172 | } |
173 | | | 173 | |
174 | /* adhoc backoff timer */ | | 174 | /* adhoc backoff timer */ |
175 | if (reconretries < 10) { | | 175 | if (reconretries < 10) { |
176 | usleep(100000 * reconretries); | | 176 | usleep(100000 * reconretries); |
177 | } else { | | 177 | } else { |
178 | sleep(MIN(10, reconretries-9)); | | 178 | sleep(MIN(10, reconretries-9)); |
179 | } | | 179 | } |
| @@ -834,29 +834,31 @@ rumpclient_init(void) | | | @@ -834,29 +834,31 @@ rumpclient_init(void) |
834 | | | 834 | |
835 | sigfillset(&fullset); | | 835 | sigfillset(&fullset); |
836 | | | 836 | |
837 | /* | | 837 | /* |
838 | * sag mir, wo die symbols sind. zogen fort, der krieg beginnt. | | 838 | * sag mir, wo die symbols sind. zogen fort, der krieg beginnt. |
839 | * wann wird man je verstehen? wann wird man je verstehen? | | 839 | * wann wird man je verstehen? wann wird man je verstehen? |
840 | */ | | 840 | */ |
841 | #ifdef RTLD_NEXT | | 841 | #ifdef RTLD_NEXT |
842 | #define FINDSYM2(_name_,_syscall_) \ | | 842 | #define FINDSYM2(_name_,_syscall_) \ |
843 | if ((host_##_name_ = rumphijack_dlsym(RTLD_NEXT, \ | | 843 | if ((host_##_name_ = rumphijack_dlsym(RTLD_NEXT, \ |
844 | #_syscall_)) == NULL) { \ | | 844 | #_syscall_)) == NULL) { \ |
845 | if (rumphijack_dlsym == rumpclient__dlsym) \ | | 845 | if (rumphijack_dlsym == rumpclient__dlsym) \ |
846 | host_##_name_ = _name_; /* static fallback */ \ | | 846 | host_##_name_ = _name_; /* static fallback */ \ |
847 | if (host_##_name_ == NULL) \ | | 847 | if (host_##_name_ == NULL) { \ |
848 | errx(1, "cannot find %s: %s", #_syscall_, \ | | 848 | fprintf(stderr,"cannot find %s: %s", #_syscall_,\ |
849 | dlerror()); \ | | 849 | dlerror()); \ |
| | | 850 | exit(1); \ |
| | | 851 | } \ |
850 | } | | 852 | } |
851 | #else | | 853 | #else |
852 | #define FINDSYM2(_name_,_syscall) \ | | 854 | #define FINDSYM2(_name_,_syscall) \ |
853 | host_##_name_ = _name_; | | 855 | host_##_name_ = _name_; |
854 | #endif | | 856 | #endif |
855 | #define FINDSYM(_name_) FINDSYM2(_name_,_name_) | | 857 | #define FINDSYM(_name_) FINDSYM2(_name_,_name_) |
856 | #ifdef __NetBSD__ | | 858 | #ifdef __NetBSD__ |
857 | FINDSYM2(socket,__socket30) | | 859 | FINDSYM2(socket,__socket30) |
858 | #else | | 860 | #else |
859 | FINDSYM(socket) | | 861 | FINDSYM(socket) |
860 | #endif | | 862 | #endif |
861 | | | 863 | |
862 | FINDSYM(close) | | 864 | FINDSYM(close) |
| @@ -1140,34 +1142,60 @@ rumpclient_exec(const char *path, char * | | | @@ -1140,34 +1142,60 @@ rumpclient_exec(const char *path, char * |
1140 | newenv[nelem+2] = NULL; | | 1142 | newenv[nelem+2] = NULL; |
1141 | | | 1143 | |
1142 | rv = host_execve(path, argv, newenv); | | 1144 | rv = host_execve(path, argv, newenv); |
1143 | | | 1145 | |
1144 | _DIAGASSERT(rv != 0); | | 1146 | _DIAGASSERT(rv != 0); |
1145 | sverrno = errno; | | 1147 | sverrno = errno; |
1146 | free(envstr2); | | 1148 | free(envstr2); |
1147 | free(envstr); | | 1149 | free(envstr); |
1148 | free(newenv); | | 1150 | free(newenv); |
1149 | errno = sverrno; | | 1151 | errno = sverrno; |
1150 | return rv; | | 1152 | return rv; |
1151 | } | | 1153 | } |
1152 | | | 1154 | |
| | | 1155 | /* |
| | | 1156 | * daemon() is handwritten for the benefit of platforms which |
| | | 1157 | * do not support daemon(). |
| | | 1158 | */ |
1153 | int | | 1159 | int |
1154 | rumpclient_daemon(int nochdir, int noclose) | | 1160 | rumpclient_daemon(int nochdir, int noclose) |
1155 | { | | 1161 | { |
1156 | struct rumpclient_fork *rf; | | 1162 | struct rumpclient_fork *rf; |
1157 | int sverrno; | | 1163 | int sverrno; |
1158 | | | 1164 | |
1159 | if ((rf = rumpclient_prefork()) == NULL) | | 1165 | if ((rf = rumpclient_prefork()) == NULL) |
1160 | return -1; | | 1166 | return -1; |
1161 | | | 1167 | |
1162 | if (daemon(nochdir, noclose) == -1) { | | 1168 | switch (fork()) { |
1163 | sverrno = errno; | | 1169 | case 0: |
1164 | rumpclient_fork_cancel(rf); | | 1170 | break; |
1165 | errno = sverrno; | | 1171 | case -1: |
1166 | return -1; | | 1172 | goto daemonerr; |
| | | 1173 | default: |
| | | 1174 | _exit(0); |
1167 | } | | 1175 | } |
1168 | | | 1176 | |
| | | 1177 | if (setsid() == -1) |
| | | 1178 | goto daemonerr; |
| | | 1179 | if (!nochdir && chdir("/") == -1) |
| | | 1180 | goto daemonerr; |
| | | 1181 | if (!noclose) { |
| | | 1182 | int fd = open("/dev/null", O_RDWR); |
| | | 1183 | dup2(fd, 0); |
| | | 1184 | dup2(fd, 1); |
| | | 1185 | dup2(fd, 2); |
| | | 1186 | if (fd > 2) |
| | | 1187 | close(fd); |
| | | 1188 | } |
| | | 1189 | |
| | | 1190 | /* note: fork is either completed or cancelled by the call */ |
1169 | if (rumpclient_fork_init(rf) == -1) | | 1191 | if (rumpclient_fork_init(rf) == -1) |
1170 | return -1; | | 1192 | return -1; |
1171 | | | 1193 | |
1172 | return 0; | | 1194 | return 0; |
| | | 1195 | |
| | | 1196 | daemonerr: |
| | | 1197 | sverrno = errno; |
| | | 1198 | rumpclient_fork_cancel(rf); |
| | | 1199 | errno = sverrno; |
| | | 1200 | return -1; |
1173 | } | | 1201 | } |