+
+static int mount_device(struct discover_device *dev)
+{
+ const char *fstype;
+ int rc;
+
+ if (!dev->device_path)
+ return -1;
+
+ if (dev->mounted)
+ return 0;
+
+ if (check_existing_mount(dev))
+ return 0;
+
+ fstype = discover_device_get_param(dev, "ID_FS_TYPE");
+ if (!fstype)
+ return 0;
+
+ dev->mount_path = join_paths(dev, mount_base(),
+ dev->device_path);
+
+ if (pb_mkdir_recursive(dev->mount_path)) {
+ pb_log("couldn't create mount directory %s: %s\n",
+ dev->mount_path, strerror(errno));
+ goto err_free;
+ }
+
+ pb_log("mounting device %s read-only\n", dev->device_path);
+ errno = 0;
+ rc = mount(dev->device_path, dev->mount_path, fstype,
+ MS_RDONLY | MS_SILENT, "");
+ if (!rc) {
+ dev->mounted = true;
+ dev->mounted_rw = false;
+ dev->unmount = true;
+ return 0;
+ }
+
+ pb_log("couldn't mount device %s: mount failed: %s\n",
+ dev->device_path, strerror(errno));
+
+ pb_rmdir_recursive(mount_base(), dev->mount_path);
+err_free:
+ talloc_free(dev->mount_path);
+ dev->mount_path = NULL;
+ return -1;
+}
+
+static int umount_device(struct discover_device *dev)
+{
+ int rc;
+
+ if (!dev->mounted || !dev->unmount)
+ return 0;
+
+ pb_log("unmounting device %s\n", dev->device_path);
+ rc = umount(dev->mount_path);
+ if (rc)
+ return -1;
+
+ dev->mounted = false;
+
+ pb_rmdir_recursive(mount_base(), dev->mount_path);
+
+ talloc_free(dev->mount_path);
+ dev->mount_path = NULL;
+
+ return 0;
+}
+
+int device_request_write(struct discover_device *dev, bool *release)
+{
+ int rc;
+
+ *release = false;
+
+ if (!dev->mounted)
+ return -1;
+
+ if (dev->mounted_rw)
+ return 0;
+
+ pb_log("remounting device %s read-write\n", dev->device_path);
+ rc = mount(dev->device_path, dev->mount_path, "",
+ MS_REMOUNT | MS_SILENT, "");
+ if (rc)
+ return -1;
+
+ dev->mounted_rw = true;
+ *release = true;
+ return 0;
+}
+
+void device_release_write(struct discover_device *dev, bool release)
+{
+ if (!release)
+ return;
+
+ pb_log("remounting device %s read-only\n", dev->device_path);
+ mount(dev->device_path, dev->mount_path, "",
+ MS_REMOUNT | MS_RDONLY | MS_SILENT, "");
+ dev->mounted_rw = false;
+}
+
+#else
+
+static int device_handler_init_sources(
+ struct device_handler *handler __attribute__((unused)))
+{
+ return 0;
+}
+
+static void device_handler_reinit_sources(
+ struct device_handler *handler __attribute__((unused)))
+{
+}
+
+static int umount_device(struct discover_device *dev __attribute__((unused)))
+{
+ return 0;
+}
+
+static int __attribute__((unused)) mount_device(
+ struct discover_device *dev __attribute__((unused)))
+{
+ return 0;
+}
+
+int device_request_write(struct discover_device *dev __attribute__((unused)),
+ bool *release)
+{
+ *release = true;
+ return 0;
+}
+
+void device_release_write(struct discover_device *dev __attribute__((unused)),
+ bool release __attribute__((unused)))
+{
+}
+
+#endif
+