+typedef struct {
+ bool is_mounted;
+ bool just_mounted;
+ bool just_changed;
+} MountSetupFlags;
+
+static int mount_setup_new_unit(
+ Unit *u,
+ const char *what,
+ const char *where,
+ const char *options,
+ const char *fstype,
+ MountSetupFlags *flags) {
+
+ MountParameters *p;
+
+ assert(u);
+ assert(flags);
+
+ u->source_path = strdup("/proc/self/mountinfo");
+ MOUNT(u)->where = strdup(where);
+ if (!u->source_path || !MOUNT(u)->where)
+ return -ENOMEM;
+
+ /* Make sure to initialize those fields before mount_is_extrinsic(). */
+ MOUNT(u)->from_proc_self_mountinfo = true;
+ p = &MOUNT(u)->parameters_proc_self_mountinfo;
+
+ p->what = strdup(what);
+ p->options = strdup(options);
+ p->fstype = strdup(fstype);
+ if (!p->what || !p->options || !p->fstype)
+ return -ENOMEM;
+
+ if (!mount_is_extrinsic(MOUNT(u))) {
+ const char *target;
+ int r;
+
+ target = mount_is_network(p) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
+ r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT);
+ if (r < 0)
+ return r;
+
+ r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT);
+ if (r < 0)
+ return r;
+ }
+
+ unit_add_to_load_queue(u);
+ flags->is_mounted = true;
+ flags->just_mounted = true;
+ flags->just_changed = true;
+
+ return 0;
+}
+
+static int mount_setup_existing_unit(
+ Unit *u,
+ const char *what,
+ const char *where,
+ const char *options,
+ const char *fstype,
+ MountSetupFlags *flags) {
+
+ MountParameters *p;
+ bool load_extras = false;
+ int r1, r2, r3;
+
+ assert(u);
+ assert(flags);
+
+ if (!MOUNT(u)->where) {
+ MOUNT(u)->where = strdup(where);
+ if (!MOUNT(u)->where)
+ return -ENOMEM;
+ }
+
+ /* Make sure to initialize those fields before mount_is_extrinsic(). */
+ p = &MOUNT(u)->parameters_proc_self_mountinfo;
+
+ r1 = free_and_strdup(&p->what, what);
+ r2 = free_and_strdup(&p->options, options);
+ r3 = free_and_strdup(&p->fstype, fstype);
+ if (r1 < 0 || r2 < 0 || r3 < 0)
+ return -ENOMEM;
+
+ flags->just_changed = r1 > 0 || r2 > 0 || r3 > 0;
+ flags->is_mounted = true;
+ flags->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
+
+ MOUNT(u)->from_proc_self_mountinfo = true;
+
+ if (!mount_is_extrinsic(MOUNT(u)) && mount_is_network(p)) {
+ /* _netdev option may have shown up late, or on a
+ * remount. Add remote-fs dependencies, even though
+ * local-fs ones may already be there.
+ *
+ * Note: due to a current limitation (we don't track
+ * in the dependency "Set*" objects who created a
+ * dependency), we can only add deps, never lose them,
+ * until the next full daemon-reload. */
+ unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT);
+ load_extras = true;
+ }
+
+ if (u->load_state == UNIT_NOT_FOUND) {
+ u->load_state = UNIT_LOADED;
+ u->load_error = 0;
+
+ /* Load in the extras later on, after we
+ * finished initialization of the unit */
+
+ /* FIXME: since we're going to load the unit later on, why setting load_extras=true ? */
+ load_extras = true;
+ flags->just_changed = true;
+ }
+
+ if (load_extras)
+ return mount_add_extras(MOUNT(u));
+
+ return 0;
+}
+