Revision 7860a380
b/qemu-nbd.c | ||
---|---|---|
41 | 41 |
static int verbose; |
42 | 42 |
static char *srcpath; |
43 | 43 |
static char *sockpath; |
44 |
static bool sigterm_reported;
|
|
45 |
static bool nbd_started;
|
|
44 |
static int persistent = 0;
|
|
45 |
static enum { RUNNING, TERMINATE, TERMINATING, TERMINATED } state;
|
|
46 | 46 |
static int shared = 1; |
47 | 47 |
static int nb_fds; |
48 | 48 |
|
... | ... | |
186 | 186 |
|
187 | 187 |
static void termsig_handler(int signum) |
188 | 188 |
{ |
189 |
sigterm_reported = true;
|
|
189 |
state = TERMINATE;
|
|
190 | 190 |
qemu_notify_event(); |
191 | 191 |
} |
192 | 192 |
|
... | ... | |
269 | 269 |
return nb_fds < shared; |
270 | 270 |
} |
271 | 271 |
|
272 |
static void nbd_export_closed(NBDExport *exp) |
|
273 |
{ |
|
274 |
assert(state == TERMINATING); |
|
275 |
state = TERMINATED; |
|
276 |
} |
|
277 |
|
|
272 | 278 |
static void nbd_client_closed(NBDClient *client) |
273 | 279 |
{ |
274 | 280 |
nb_fds--; |
281 |
if (nb_fds == 0 && !persistent && state == RUNNING) { |
|
282 |
state = TERMINATE; |
|
283 |
} |
|
275 | 284 |
qemu_notify_event(); |
285 |
nbd_client_put(client); |
|
276 | 286 |
} |
277 | 287 |
|
278 | 288 |
static void nbd_accept(void *opaque) |
... | ... | |
282 | 292 |
socklen_t addr_len = sizeof(addr); |
283 | 293 |
|
284 | 294 |
int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len); |
285 |
nbd_started = true; |
|
295 |
if (state >= TERMINATE) { |
|
296 |
close(fd); |
|
297 |
return; |
|
298 |
} |
|
299 |
|
|
286 | 300 |
if (fd >= 0 && nbd_client_new(exp, fd, nbd_client_closed)) { |
287 | 301 |
nb_fds++; |
288 | 302 |
} |
... | ... | |
329 | 343 |
int partition = -1; |
330 | 344 |
int ret; |
331 | 345 |
int fd; |
332 |
int persistent = 0; |
|
333 | 346 |
bool seen_cache = false; |
334 | 347 |
#ifdef CONFIG_LINUX_AIO |
335 | 348 |
bool seen_aio = false; |
... | ... | |
546 | 559 |
} |
547 | 560 |
} |
548 | 561 |
|
549 |
exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, NULL);
|
|
562 |
exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, nbd_export_closed);
|
|
550 | 563 |
|
551 | 564 |
if (sockpath) { |
552 | 565 |
fd = unix_socket_incoming(sockpath); |
... | ... | |
581 | 594 |
err(EXIT_FAILURE, "Could not chdir to root directory"); |
582 | 595 |
} |
583 | 596 |
|
597 |
state = RUNNING; |
|
584 | 598 |
do { |
585 | 599 |
main_loop_wait(false); |
586 |
} while (!sigterm_reported && (persistent || !nbd_started || nb_fds > 0)); |
|
600 |
if (state == TERMINATE) { |
|
601 |
state = TERMINATING; |
|
602 |
nbd_export_close(exp); |
|
603 |
nbd_export_put(exp); |
|
604 |
exp = NULL; |
|
605 |
} |
|
606 |
} while (state != TERMINATED); |
|
587 | 607 |
|
588 |
nbd_export_close(exp); |
|
589 |
nbd_export_put(exp); |
|
590 | 608 |
bdrv_close(bs); |
591 |
|
|
592 | 609 |
if (sockpath) { |
593 | 610 |
unlink(sockpath); |
594 | 611 |
} |
Also available in: Unified diff