| 716 | } |
| 717 | |
| 718 | static int ublk_start_daemon(struct ublk_dev *dev) |
| 719 | { |
| 720 | int ret, i; |
| 721 | void *thread_ret; |
| 722 | const struct ublksrv_ctrl_dev_info *dinfo = &dev->dev_info; |
| 723 | |
| 724 | if (daemon(1, 1) < 0) |
| 725 | return -errno; |
| 726 | |
| 727 | ublk_dbg(UBLK_DBG_DEV, "%s enter\n", __func__); |
| 728 | |
| 729 | ret = ublk_dev_prep(dev); |
| 730 | if (ret) |
| 731 | return ret; |
| 732 | |
| 733 | for (i = 0; i < dinfo->nr_hw_queues; i++) { |
| 734 | dev->q[i].dev = dev; |
| 735 | dev->q[i].q_id = i; |
| 736 | pthread_create(&dev->q[i].thread, NULL, |
| 737 | ublk_io_handler_fn, |
| 738 | &dev->q[i]); |
| 739 | } |
| 740 | |
| 741 | /* everything is fine now, start us */ |
| 742 | ublk_set_parameters(dev); |
| 743 | ret = ublk_ctrl_start_dev(dev, getpid()); |
| 744 | if (ret < 0) { |
| 745 | ublk_err("%s: ublk_ctrl_start_dev failed: %d\n", __func__, ret); |
| 746 | goto fail; |
| 747 | } |
| 748 | |
| 749 | /* wait until we are terminated */ |
| 750 | for (i = 0; i < dinfo->nr_hw_queues; i++) |
| 751 | pthread_join(dev->q[i].thread, &thread_ret); |
| 752 | fail: |
| 753 | ublk_dev_unprep(dev); |
| 754 | ublk_dbg(UBLK_DBG_DEV, "%s exit\n", __func__); |
| 755 | |
| 756 | return ret; |
| 757 | } |
| 758 | |
| 759 | static int wait_ublk_dev(char *dev_name, int evt_mask, unsigned timeout) |
| 760 | { |
no test coverage detected