-struct msg_unmount_request {
- struct unmount_msg_hdr hdr;
- u32 unmount_flags;
- u8 want_progress_messages;
-} PACKED;
-
-struct msg_daemon_info {
- struct unmount_msg_hdr hdr;
- pid_t daemon_pid;
- u32 mount_flags;
-} PACKED;
-
-struct msg_unmount_finished {
- struct unmount_msg_hdr hdr;
- int32_t status;
-} PACKED;
-
-struct msg_write_streams_progress {
- struct unmount_msg_hdr hdr;
- union wimlib_progress_info info;
-} PACKED;
-
-enum {
- MSG_TYPE_UNMOUNT_REQUEST,
- MSG_TYPE_DAEMON_INFO,
- MSG_TYPE_WRITE_STREAMS_PROGRESS,
- MSG_TYPE_UNMOUNT_FINISHED,
- MSG_TYPE_MAX,
-};
-
-struct msg_handler_context_hdr {
- int timeout_seconds;
-};
-
-struct unmount_msg_handler_context {
- struct msg_handler_context_hdr hdr;
- pid_t daemon_pid;
- int mount_flags;
- int status;
- wimlib_progress_func_t progress_func;
-};
-
-struct daemon_msg_handler_context {
- struct msg_handler_context_hdr hdr;
- struct wimfs_context *wimfs_ctx;
-};
-
-static int send_unmount_request_msg(mqd_t mq, int unmount_flags,
- u8 want_progress_messages)
-{
- DEBUG("Sending unmount request msg");
- struct msg_unmount_request msg = {
- .hdr = {
- .min_version = WIMLIB_MAKEVERSION(1, 2, 1),
- .cur_version = WIMLIB_VERSION_CODE,
- .msg_type = MSG_TYPE_UNMOUNT_REQUEST,
- .msg_size = sizeof(msg),
- },
- .unmount_flags = unmount_flags,
- .want_progress_messages = want_progress_messages,
- };
-
- if (mq_send(mq, (void*)&msg, sizeof(msg), 1)) {
- ERROR_WITH_ERRNO("Failed to communicate with filesystem daemon");
- return WIMLIB_ERR_MQUEUE;
- }
- return 0;
-}
-
-static int send_daemon_info_msg(mqd_t mq, pid_t pid, int mount_flags)
-{
- DEBUG("Sending daemon info msg (pid = %d, mount_flags=%x)",
- pid, mount_flags);
-
- struct msg_daemon_info msg = {
- .hdr = {
- .min_version = WIMLIB_MAKEVERSION(1, 2, 1),
- .cur_version = WIMLIB_VERSION_CODE,
- .msg_type = MSG_TYPE_DAEMON_INFO,
- .msg_size = sizeof(msg),
- },
- .daemon_pid = pid,
- .mount_flags = mount_flags,
- };
- if (mq_send(mq, (void*)&msg, sizeof(msg), 1)) {
- ERROR_WITH_ERRNO("Failed to send daemon info to unmount process");
- return WIMLIB_ERR_MQUEUE;
- }
- return 0;
-}
-
-static void send_unmount_finished_msg(mqd_t mq, int status)
-{
- DEBUG("Sending unmount finished msg");
- struct msg_unmount_finished msg = {
- .hdr = {
- .min_version = WIMLIB_MAKEVERSION(1, 2, 1),
- .cur_version = WIMLIB_VERSION_CODE,
- .msg_type = MSG_TYPE_UNMOUNT_FINISHED,
- .msg_size = sizeof(msg),
- },
- .status = status,
- };
- if (mq_send(mq, (void*)&msg, sizeof(msg), 1))
- ERROR_WITH_ERRNO("Failed to send status to unmount process");
-}
-
-static int unmount_progress_func(enum wimlib_progress_msg msg,
- const union wimlib_progress_info *info)
-{
- if (msg == WIMLIB_PROGRESS_MSG_WRITE_STREAMS) {
- struct msg_write_streams_progress msg = {
- .hdr = {
- .min_version = WIMLIB_MAKEVERSION(1, 2, 1),
- .cur_version = WIMLIB_VERSION_CODE,
- .msg_type = MSG_TYPE_WRITE_STREAMS_PROGRESS,
- .msg_size = sizeof(msg),
- },
- .info = *info,
- };
- if (mq_send(wimfs_get_context()->daemon_to_unmount_mq,
- (void*)&msg, sizeof(msg), 1))
- {
- ERROR_WITH_ERRNO("Failed to send progress information "
- "to unmount process");
- }
- }
- return 0;
-}
-
-static int msg_unmount_request_handler(const void *_msg, void *_handler_ctx)
-{
- const struct msg_unmount_request *msg = _msg;
- struct daemon_msg_handler_context *handler_ctx = _handler_ctx;
- struct wimfs_context *wimfs_ctx;
- int status = 0;
- int ret;
- int unmount_flags;
- wimlib_progress_func_t progress_func;
-
- DEBUG("Handling unmount request msg");
-
- wimfs_ctx = handler_ctx->wimfs_ctx;
- if (msg->hdr.msg_size < sizeof(*msg)) {
- status = WIMLIB_ERR_INVALID_UNMOUNT_MESSAGE;
- goto out;
- }
-
- unmount_flags = msg->unmount_flags;
- if (msg->want_progress_messages)
- progress_func = unmount_progress_func;