<!--
Mount:
- @options: Options - known options (in addition to <link linkend="udisks-std-options">standard options</link>) includes <parameter>fstype</parameter> (of type 's'), <parameter>options</parameter> (of type 's') and <parameter>loop.autoclear</parameter> (of type 'b').
+ @options: Options - known options (in addition to <link linkend="udisks-std-options">standard options</link>) includes <parameter>fstype</parameter> (of type 's') and <parameter>options</parameter> (of type 's').
@mount_path: The filesystem path where the device was mounted.
Mounts the filesystem.
filesystem types are validated against a (small) whitelist to
avoid unexpected privilege escalation
- The @loop.autoclear option can be used on loop devices to
- request that the underlying loop device is cleared when the
- filesystem is unmounted.
-
If the device in question is referenced in the
<filename>/etc/fstab</filename> file, the
<command>mount</command> command is called directly (as root)
<arg choice="plain">--filesystem-type <replaceable>TYPE</replaceable></arg>
</group>
<arg choice="opt" rep="repeat">--options <replaceable>OPTIONS</replaceable></arg>
- <arg choice="opt">--loop-autoclear</arg>
<arg choice="opt">--no-user-interaction</arg>
</cmdsynopsis>
<parameter>dev</parameter> that would allow the caller to
gain additional privileges, are rejected.
</para>
- <para>
- The option <option>--loop-autoclear</option> can be used
- on loop devices to request that the kernel clears the loop
- device when the last closer closes the device - e.g. right
- after the filesystem is unmounted.
- </para>
</listitem>
</varlistentry>
#include <sys/acl.h>
#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#include <linux/loop.h>
-
#include <glib/gstdio.h>
#include "udiskslogging.h"
/* ---------------------------------------------------------------------------------------------------- */
-static gboolean
-loop_set_autoclear (const gchar *device,
- GError **error)
-{
- gboolean ret = FALSE;
- struct loop_info64 li64;
- gint fd = -1;
-
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- fd = open (device, O_RDWR);
- if (fd == -1)
- {
- g_set_error (error,
- G_IO_ERROR,
- g_io_error_from_errno (errno),
- "Error opening loop device %s: %m",
- device);
- goto out;
- }
-
- memset (&li64, '\0', sizeof (li64));
- if (ioctl (fd, LOOP_GET_STATUS64, &li64) < 0)
- {
- g_set_error (error,
- G_IO_ERROR,
- g_io_error_from_errno (errno),
- "Error getting status for loop device %s: %m",
- device);
- goto out;
- }
-
- li64.lo_flags |= LO_FLAGS_AUTOCLEAR;
-
- if (ioctl (fd, LOOP_SET_STATUS64, &li64) < 0)
- {
- g_set_error (error,
- G_IO_ERROR,
- g_io_error_from_errno (errno),
- "Error setting status for loop device %s: %m",
- device);
- goto out;
- }
-
- ret = TRUE;
-
- out:
- if (fd != -1 )
- {
- if (close (fd) != 0)
- udisks_warning ("close(2) on loop fd %d for device %s failed: %m", fd, device);
- }
- return ret;
-}
-
-
/* runs in thread dedicated to handling @invocation */
static gboolean
handle_mount (UDisksFilesystem *filesystem,
const gchar *message;
gboolean system_managed;
gchar *escaped_device = NULL;
- gboolean opt_loop_autoclear = FALSE;
object = NULL;
error_message = NULL;
daemon = udisks_linux_block_object_get_daemon (UDISKS_LINUX_BLOCK_OBJECT (object));
cleanup = udisks_daemon_get_cleanup (daemon);
- if (options != NULL)
- {
- g_variant_lookup (options,
- "loop.autoclear",
- "b",
- &opt_loop_autoclear);
- }
-
/* check if mount point is managed by e.g. /etc/fstab or similar */
if (is_system_managed (block, &mount_point_to_use, &fstab_mount_options))
{
caller_uid,
FALSE); /* fstab_mounted */
- if (opt_loop_autoclear)
- {
- error = NULL;
- if (!loop_set_autoclear (udisks_block_get_device (block), &error))
- {
- g_dbus_method_invocation_take_error (invocation, error);
- goto out;
- }
- }
-
udisks_notice ("Mounted %s at %s on behalf of uid %d",
udisks_block_get_device (block),
mount_point_to_use,
static gchar *opt_mount_unmount_device = NULL;
static gchar *opt_mount_options = NULL;
static gchar *opt_mount_filesystem_type = NULL;
-static gboolean opt_mount_loop_autoclear = FALSE;
static gboolean opt_unmount_force = FALSE;
static gboolean opt_mount_unmount_no_user_interaction = FALSE;
NULL
},
{
- "loop-autoclear",
- 0,
- 0,
- G_OPTION_ARG_NONE,
- &opt_mount_loop_autoclear,
- "Clear the loop device after unmounting",
- NULL
- },
- {
"no-user-interaction",
0, /* no short option */
0,
opt_mount_unmount_device = NULL;
opt_mount_options = NULL;
opt_mount_filesystem_type = NULL;
- opt_mount_loop_autoclear = FALSE;
opt_unmount_force = FALSE;
object = NULL;
options = NULL;
"{sv}",
"fstype", g_variant_new_string (opt_mount_filesystem_type));
}
- if (opt_mount_loop_autoclear)
- {
- g_variant_builder_add (&builder,
- "{sv}",
- "loop.autoclear", g_variant_new_boolean (TRUE));
- }
}
else
{