- dir_path = realpath(mount_dir, NULL);
- if (!dir_path) {
- ERROR_WITH_ERRNO("Failed to resolve path \"%s\"", mount_dir);
- if (errno == ENOMEM)
- return WIMLIB_ERR_NOMEM;
- else
- return WIMLIB_ERR_NOTDIR;
- }
-
- p = dir_path;
- while (*p) {
- if (*p == '/')
- *p = 0xff;
- p++;
- }
-
- ctx->unmount_to_daemon_mq_name = strcat_dup(u2d_prefix, dir_path,
- NAME_MAX);
- if (!ctx->unmount_to_daemon_mq_name) {
- ret = WIMLIB_ERR_NOMEM;
- goto out_free_dir_path;
- }
- ctx->daemon_to_unmount_mq_name = strcat_dup(d2u_prefix, dir_path,
- NAME_MAX);
- if (!ctx->daemon_to_unmount_mq_name) {
- ret = WIMLIB_ERR_NOMEM;
- goto out_free_unmount_to_daemon_mq_name;
- }
-
- ret = 0;
- goto out_free_dir_path;
-out_free_unmount_to_daemon_mq_name:
- FREE(ctx->unmount_to_daemon_mq_name);
- ctx->unmount_to_daemon_mq_name = NULL;
-out_free_dir_path:
- FREE(dir_path);
- return ret;
-}
-
-static void free_message_queue_names(struct wimfs_context *ctx)
-{
- FREE(ctx->unmount_to_daemon_mq_name);
- FREE(ctx->daemon_to_unmount_mq_name);
- ctx->unmount_to_daemon_mq_name = NULL;
- ctx->daemon_to_unmount_mq_name = NULL;
-}
-
-/*
- * Opens two POSIX message queue: one for sending messages from the unmount
- * process to the daemon process, and one to go the other way. The names of the
- * message queues, which must be system-wide unique, are be based on the mount
- * point.
- *
- * @daemon specifies whether the calling process is the filesystem daemon or the
- * unmount process.
- */
-static int open_message_queues(struct wimfs_context *ctx, bool daemon)
-{
- int unmount_to_daemon_mq_flags = O_WRONLY | O_CREAT;
- int daemon_to_unmount_mq_flags = O_RDONLY | O_CREAT;
-
- if (daemon)
- swap(unmount_to_daemon_mq_flags, daemon_to_unmount_mq_flags);
-
- DEBUG("Opening message queue \"%s\"", ctx->unmount_to_daemon_mq_name);
- ctx->unmount_to_daemon_mq = mq_open(ctx->unmount_to_daemon_mq_name,
- unmount_to_daemon_mq_flags, 0700, NULL);
-
- if (ctx->unmount_to_daemon_mq == (mqd_t)-1) {
- ERROR_WITH_ERRNO("mq_open()");
- return WIMLIB_ERR_MQUEUE;
- }
-
- DEBUG("Opening message queue \"%s\"", ctx->daemon_to_unmount_mq_name);
- ctx->daemon_to_unmount_mq = mq_open(ctx->daemon_to_unmount_mq_name,
- daemon_to_unmount_mq_flags, 0700, NULL);
-
- if (ctx->daemon_to_unmount_mq == (mqd_t)-1) {
- ERROR_WITH_ERRNO("mq_open()");
- mq_close(ctx->unmount_to_daemon_mq);
- mq_unlink(ctx->unmount_to_daemon_mq_name);
- ctx->unmount_to_daemon_mq = (mqd_t)-1;
- return WIMLIB_ERR_MQUEUE;
- }
- return 0;
-}
-
-/* Try to determine the maximum message size of a message queue. The return
- * value is the maximum message size, or a guess of 8192 bytes if it cannot be
- * determined. */
-static long mq_get_msgsize(mqd_t mq)
-{
- static const char *msgsize_max_file = "/proc/sys/fs/mqueue/msgsize_max";
- FILE *fp;
- struct mq_attr attr;
- long msgsize;
-
- if (mq_getattr(mq, &attr) == 0) {
- msgsize = attr.mq_msgsize;
- } else {
- ERROR_WITH_ERRNO("mq_getattr()");
- ERROR("Attempting to read %s", msgsize_max_file);
- fp = fopen(msgsize_max_file, "rb");
- if (fp) {
- if (fscanf(fp, "%ld", &msgsize) != 1) {
- ERROR("Assuming message size of 8192");
- msgsize = 8192;
- }
- fclose(fp);
- } else {
- ERROR_WITH_ERRNO("Failed to open the file `%s'",
- msgsize_max_file);
- ERROR("Assuming message size of 8192");
- msgsize = 8192;
- }
- }
- return msgsize;
-}
-
-static int get_mailbox(mqd_t mq, long needed_msgsize, long *msgsize_ret,
- void **mailbox_ret)
-{
- long msgsize;
- char *mailbox;
-
- msgsize = mq_get_msgsize(mq);
+ /* Create 'replace_imd' structure to use for the reset original,
+ * unmodified image. */
+ ret = WIMLIB_ERR_NOMEM;
+ replace_imd = new_image_metadata();
+ if (!replace_imd)
+ goto err;
+
+ /* Create new stream reference for the modified image's metadata
+ * resource, which doesn't exist yet. */
+ ret = WIMLIB_ERR_NOMEM;
+ new_lte = new_lookup_table_entry();
+ if (!new_lte)
+ goto err_put_replace_imd;
+ new_lte->flags = WIM_RESHDR_FLAG_METADATA;
+ new_lte->unhashed = 1;
+
+ /* Make the image being moved available at a new index. Increments the
+ * WIM's image count, but does not increment the reference count of the
+ * 'struct image_metadata'. */
+ ret = append_image_metadata(wim, imd);
+ if (ret)
+ goto err_free_new_lte;