U盘的热拔插/自动挂载跟linux2.6 kernel、 udev、 hal、 dbus 、gnomemount 、thunar的关系

插入新设备后,
kernel 发现设备变化反应到 sysfs 上并通知 udev,
udev 把硬件相关内容送给 hal,
hal 过滤、处理之后发送信息到 dbus 总线,
thunar 从 dbus 收到信息后在 xfdesktop 桌面显示新图标,
用户点击桌面图标后用 pmount 把设备挂上,打开挂载 目录。

具体的说就是:

 这是当时的情况,如今小有变化,gnome缺省使用 gnome-mount 而不是 pmount 了,gnome-mount 使用 gconf-editor 配置,而不是 pmount 的策略,其余机制没啥变化。

(原发于BBS Linux 版面)

关键字: sysfs, hotplug, udev, hal, gnome-volume-manager, pmount

关于自动挂载可移动存储介质,譬如 u 盘啥的一直是很多人想要实现的东东,缺省的,对于高版本内核的系统,gnome 里面是可以这样的,这个原因恐怕很多人还不是很清楚,那天看了两眼,来解释一下,有啥不对的地方,还请指出
 
自动挂载磁盘分区的操作从底层来说,是要内核支持的,2.6 内核的sysfs 虚拟文件系统就提供了这一支持,这个文件系统 (/sys/) 通常用于反应系统硬件信息,总线上的设备变化、网络设备的变化等事件在这里都能反应出来,这个文件系统的变化配合上内核的 hotplug 机制就可以掌握硬件改动相关的信息了。
 
说到内核的 hotplug 机制,简单地说就是在硬件发生变化的时候去通知某一用户态程序,缺省是 /sbin/hotplug,不过现在它已经被 udev 取代了,收到信息之后,udev 会根据 sysfs 的变化调用一些脚本来处理这个事件,这里的处理是指某个用户空间的动作,而不是加载驱动,加载驱动是内核自己的事情,在 udev 反应过来之前就完成了。
 
下面轮到我们著名的硬件抽象层 (HAL) 程序的了,这个程序有一个派驻到 udev 的脚本,把硬件改动信息部分地送到自己这里来处理,根据它的不同设置,有可能会提示某些东东来挂载磁盘阿、检测新进来的数码相机阿……
 
那 hal 怎么发出通知呢? 这是利用一个新兴的系统内用户空间消息总线系统 -- dbus 来完成的,hal 会通过 dbus 上的一条消息总线把新加入的块设备和相关的挂载提示信息,比如加载选项 sync, iocharset 之类的信息发送到总线上来,只等待一个终结者来接受并处理这些信息了。
 
这个终结者对于 gnome 来说就是 gnome-volume-manager (名字太长了,下面简称 gvm),它从 dbus 上探听消息,当发现有设备挂载提示的时候就会尝试把设备挂载上来。缺省的,还会打开一个 nautilus 浏览窗口来浏览新挂载上的分区的内容。
 
嗯,最后一个问题就是怎么挂了,众所周知,如果块设备在 /etc/fstab 里没有描述存在的话,挂载就比较麻烦:

  • 本来如果有 fstab 中的 user 属性的话,普通用户可以挂载,但  现在没有,普通用户没法挂
  • 如果 sudo 授权的话,用户可能获得挂载其他分区的过大权限,危及 系统安全。

pmount 就是这个工具链上的最后一环,它可以代表用户 (运行 gvm 的用户) 来挂载一个属于他的可移动存储设备,即使 fstab 里没有这个设备存在,缺省的挂载位置是 /media/ 下,和 块设备同名,比如 /dev/sda1 挂载到 /media/sda1/ 目录。
 
嗯,综上,设备的自动挂载就完成了,呵呵,希望一大堆的关键词没把大家搞晕,回顾一下: kernel 发现设备变化反应到 sysfs 上并通过 hotplug 机制通知udev, udev 把硬件相关内容送给 hal,hal 过滤、处理之后发送信息到 dbus 上,在 dbus 上等候的 gvm 收到消息后用 pmount 把设备挂上,这样,设备的自动挂载就完成了 :)

从具体实现层面来说就是:

App
↑              App等候设备处理信息并挂载设备
D-Bus
↑              过滤处理内容后送给D-Bus
HAL             它是一个位于操作系统和驱动程序之上,运行在用户空间中的服务程序
↑              把硬件相关内容送到HAL
udev
↑              kernel2.6发现设备变化反映到sysfs, 并通过hotplug机制通知udev
Linux Kernel2.6 自动调用驱动模块

1. 自动挂载磁盘分区的操作从底层来说,是要内核支持的,2.6 内核的sysfs 虚拟文件系统就提供了这一支持,这个文件系统 (/sys/) 通常用于反应系统硬件信息,总线上的设备变化、网络设备的变化等事件在这里都能反应出来,这个文件系统的变化配合上内核的 hotplug 机制就可以掌握硬件改动相关的信息.
说到内核的 hotplug 机制,简单地说就是在硬件发生变化的时候去通知某一用户态程序,缺省是 /sbin/hotplug,不过现在它已经被 udev 取代了,收到信息之后,udev 会根据 sysfs 的变化调用一些脚本来处理这个事件,这里的处理是指某个用户空间的动作,而不是加载驱动,加载驱动是内核自己的事情,在 udev 反应过来之前就完成了.

2. 下面轮到我们著名的硬件抽象层(HAL)
HAL是Hardware Abstraction Layer的首字母缩写。我最早是在Winnt 3.5的帮助中知道这个名词的,对帮助文档中的说法我比较认同,所以一直对它抱有好感。不过Windows下的HAL和Linux下的HAL两者所指并非相同之物:
Windows 下的HAL 位于操作系统的最底层,直接操作物理硬件,隔离与硬件相关的信息,为上层的操作系统和设备驱动程序提供一个统一的接口,起到对硬件的抽象作用。有了HAL,编写驱动程序就容易多了,因为HAL的接口不但使用简单,而且具有更好的可移植性(没用过)。
Linux 下的HAL :至于对硬件的抽象,Linux内核早就有类似机制,只不过没有专门的名称罢了。而Linux的HAL指的并非这个,它不是位于操作系统的最底层,直接操作硬件,相反,它位于操作系统和驱动程序之上,是一个运行在用户空间中服务程序。
我们知道,Linux和所有的Unix一样,习惯用文件来抽象设备,任何设备都是一个文件,比如/dev/mouse是鼠标的设备文件。这种方法看起来不错,每个设备都有统一的形式,但使用并不那么容易,设备文件名没有什么规范,从简单的一个文件名,你无法得知它是什么设备,具有有什么特性。
结果形成这样的尴尬:有了设备和设备驱动程序,却不知道如何使用它。这些乱七八糟的设备文件,让设备的管理和应用程序的开发都变得很麻烦,所以有必要提供一个硬件抽象层,来为上层应用程序提供一个统一的接口,Linux的HAL就这样应运而生了。
但HAL并不提供诸如拍照和刻录等之类的功能,相反它只是告诉应用程序,系统中有哪些设备可用,以及这些设备的类型、特性和能力等。主要说来,它提供以下几项功能:
1.         获取指定类型的设备列表。
2.         获取/更改设备的属性值。
3.         获取设备具有的能力描述。
4.         设备插入/拔除时,通知相关应用程序。
5.         设备属性或能力变化时,通知相关应用程序。
udev创建dev下的文件结点,加载驱动程序,让设备处于可用状态。而HAL则告诉应用程序,现在有哪些设备可用,这些设备的类型、特性和能力,让应用程序知道如何使用它们。
设备的属性管理是HAL最重要任务之一,有的设备属性来源于实际的硬件,有的来源于设备信息文件(/usr/share/hal/fdi/),有的来源其它配置信息(如/usr/share/hwdata/)。设备属性的都有标准的定义,这些属性定义是HAL的SPEC的主要内容之一,可以参考
http://people.freedesktop.org/~david/hal-spec/hal-spec.html

3.  udev & HAL
udev通过NetLink注册内核的设备事件,当有设备插入/拔除时,udev就会收到通知,它会从事件中所带参数和sysfs中的信息,加载适当的驱动程序,创建dev下的结点,让设备处于可用的状态。
.         udev只是一个框架,它的行为完全受它的规则所控制,这些规则存放在目录/etc/udev/rules.d/中,其中90-hal.rules是用来让udev把设备插入/拔除的事件通过socket socket:/org/freedesktop/hal/udev_event转发给HAL的。
.         HAL挂在socket:/org/freedesktop/hal/udev_event上等待事件,有事件发生时就调用函数 hald_udev_data处理,它先从事件中取出主要参数,创建一个hotplug_event对象,把它放入事件队列中,然后调用 hotplug_event_process_queue处理事件。
.         函数hotplug_event_begin负责具体事件的处理,它把全部事件分为四类,并分别处理 hotplug_event_begin_sysfs处理普通设备事件,hotplug_event_begin_acpi处理ACPI事件,hotplug_event_begin_apm处理APM事件,hotplug_event_begin_pmu处理PMU事件。要注意的是,后三者的事件源并非源于udev,而是在device_reprobe时触发的 (osspec_device_reprobe/hotplug_reprobe_tree /hotplug_reprobe_generate_add_events/acpi_generate_add_hotplug_event)。
.         函数hotplug_event_begin_sysfs中,如果是插入设备,则创建一个设备对象,设置设备的属性,调用相关callouts,然后放入设备列表中,并触发signal让dbus通知相关应用程序。如果是拔除设备,则调用相关callouts,然后从设备列表中删除,并触发signal 让dbus通知相关应用程序。
.         应用程序可以主动调用HAL提供的DBUS接口函数,这些函数在libhal.h中有定义。应用程序也可以注册HAL的signal,当设备变化时,HAL通过DBUS上报事件给应用程序。
.         callout是HAL一种扩展方式,它在设备插入/拔除时执行。可以在设备信息文件中(/usr/share/hal目录)指定。
.         addon也是HAL一种扩展方式,它与callout的不同之处在于addon往往是事件的触发者,而不是事件的消费者。HAL的事件源主要源于 udev,而udev源于kernel的hotplug,然而有的设备如电源设备、磁盘设备和特殊按键等,它们并不产生hotplug事件。HAL就得不到通知,怎么办呢,addon就是用于支持新事件源的扩展方式。比如addon-acpi从/proc/acpi/event或者/var/run /acpid.socket收到事件,然后转发成HAL事件。addon-storage检测光盘或磁盘的状态,并设置设备的属性。addon- keyboard检测一些特殊按键,并触发相应事件。
access-check/ci-tracker/ck-tracker负责权限的检查,里面提到的PolicyKit/ConsoleKit不是太熟悉,有时间再看看。
简单的说,HAL就是一个设备数据库,它管理当前系统中所有的设备,你可以以多种灵活的方式去查询这些设备,可以获取指定设备的特性,可以注册设备变化事件。

4. 那 hal 怎么发出通知呢? 这是利用一个新兴的系统内用户空间消息总线系统 -- dbus 来完成的,hal 会通过 dbus 上的一条消息总线把新加入的块设备和相关的挂载提示信息,比如加载选项 sync, iocharset 之类的信息发送到总线上来,只等待一个终结者来接受并处理这些信息了.

5. 这个终结者对于 gnome 来说就是 gnome-volume-manager (名字太长了,下面简称 gvm),它从 dbus 上探听消息,当发现有设备挂载提示的时候就会尝试把设备挂载上来。缺省的,还会打开一个 nautilus 浏览窗口来浏览新挂载上的分区的内容。
嗯,最后一个问题就是怎么挂了,众所周知,如果块设备在 /etc/fstab 里没有描述存在的话,挂载就比较麻烦:


  • 本来如果有 fstab 中的 user 属性的话,普通用户可以挂载,但  现在没有,普通用户没法挂
  • 如果 sudo 授权的话,用户可能获得挂载其他分区的过大权限,危及 系统安全。


pmount 就是这个工具链上的最后一环,它可以代表用户 (运行 gvm 的用户) 来挂载一个属于他的可移动存储设备,即使 fstab 里没有这个设备存在,缺省的挂载位置是 /media/ 下,和 块设备同名,比如 /dev/sda1 挂载到 /media/sda1/ 目录。

嗯,综上,设备的自动挂载就完成了,呵呵,希望一大堆的关键词没把大家搞晕,回顾一下: kernel 发现设备变化反应到 sysfs 上并通过 hotplug 机制通知udev, udev 把硬件相关内容送给 hal,hal 过滤、处理之后发送信息到 dbus 上,在 dbus 上等候的 gvm 收到消息后用 pmount 把设备挂上,这样,设备的自动挂载就完成.
PS:HAL的相关文件:
首先是硬件信息文件fdi的路径会有:
/usr/share/hal/fdi 通常是由系统程序安装包提供的文件。
/etc/hal/fdi 这里是用户或者管理员修改fdi的位置。
这两个路径下各自存在information policy preprobe等3个目录,用来存放不同用途的fdi文件。后面再解释。

其次是HAL的一些Callout和Addon,他们位于 /usr/lib/hal/scripts 及 /usr/lib/hal/ 下面

再有一些与HAL本身相关的配置文件等:
/etc/init.d/hal hal的启动脚本
/etc/udev/rules.d/95-hal.rules  HAL在UDEV中的规则
/etc/dbus-1/system.d/hal.conf  HAL的一些常用的Interface在DBUS中的权限设置。

相关程序
/usr/bin/lshal
/usr/bin/hal-device
/usr/bin/hal-get-property
/usr/bin/hal-set-property
/usr/bin/hal-find-by-capability
/usr/bin/hal-find-by-property
/usr/bin/hal-disable-polling
/usr/bin/hal-is-caller-locked-out
/usr/bin/hal-lock
/usr/sbin
/usr/sbin/hald

参考:http://blog.csdn.net/colorant/archive/2008/07/04/2611559.aspx

另外,关于HAL热拔插的文档:

http://wiki.archlinux.org/index.php/HAL_%28%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87%29

Contents

[hide ]

<script type="text/javascript"> if (window.showTocToggle) { var tocShowText = &quot;show&quot;; var tocHideText = &quot;hide&quot;; showTocToggle(); } </script>

介绍

硬件抽象层(Hardware Abstraction Layer,HAL)是一个守护进程,它允许桌面应用程序即时读取硬件信息,这样,无论接口或设备类型如何,应用程序都能找到并使用它们。用这种方法,图形界面以一种无缝、一致的模式为用户提供所有的资源。

关于热插拔

热插拔会发生很多事情,HAL只是其中一部分。当一个新设备被加入,例如插入一个U盘,会发生以下事情(粗略的):

  • 内核获知此新设备并将其注册到/sys .
  • Udev 创建一个设备节点(如/dev/sdb1 ),然后加载必需的驱动/模块。
  • HAL守护进程接到D-Bus 的通知,将设备及其相关信息加入到数据库。
  • HAL通过D-Bus将新设备的加入这件事广播给所有订阅程序,如Thunar对此将在快捷边栏上显示图标,或者Metacity/Nautilus对此会在桌面添加一个图标。
  • 可能还有其它监听程序,如卷管理器或者 AutoFS ,它被配置为自动创建挂载点并挂载某些类型的驱动器, 当iPod插入时启动Rhythmbox ,等等。

HAL并不检测硬件(内核)、管理设备或驱动(udev)或者自动挂载驱动器(卷管理器)。作为一个硬件抽象层(h ardware a bstraction l ayer),它的角色更象是一个通讯中心,为应用程序提供简洁的设备接口。热插拔设备无法正常检测、使用或挂载等问题要仔细研究调查,要知道它涉及了方方面面。(参看'疑难排解')。

关于卷挂载点

HAL在/media/某文件夹 下挂载卷。 对于某文件夹 的命名,它使用卷的标签(label) ,如果卷没有标签,它会使用卷的类型(type) (如果目录已存在则尾随数字),例如/media/disk ,、/media/disk-1 ...

要给分区命名一个标签,可以使用GParted (extra仓库中) ,或者KDE下的PartitionManager (AUR 中)。

同时请留意以下挂载设备时常见的三个问题:

  • 目录/media/label_of_your_volume 必须 存在,它会由HAL自动创建和销毁。
  • 设备必须没有 写在fstab中,否则HAL将拒绝加载它。
  • 你必须有权加载设备,详情参见 Permission Denied

如果由于某些原因你无法 给分区命名标签(label),可以设置个伪标签给HAL。你需要先准备好以下两项:

  • $device_uuid , 设备的uuid(ls -l /dev/disk/by-uuid/
  • $fake_label , 你选择的伪标签

将以下内容写入/etc/hal/fdi/policy/20-$device_name .fdi ,别忘了把$device_uuid$device_name 替换为真正的内容。

File: /etc/hal/fdi/policy/20-$device_name.fdi
 <?xml version="1.0" encoding="UTF-8"?>
 <deviceinfo version="0.2">
    <device>
        <match key="volume.uuid" string="$device_uuid
">
            <merge key="volume.label" type="string">$device_name
</merge>
        </match>
    </device>
 </deviceinfo>

安装和配置HAL

一、安装

HAL要求守护进程dbus的存在,因此我们需要把它们两个都装上:

# pacman -S dbus hal

然后以root身份编辑/rc.conf 文件,把hal 添加到DAEMONS列,例如:

DAEMONS=(syslog-ng dbus hal
 network netfs ...)

现在DBUS和HAL守护进程就会在启动时加载了。由于如果dbus没有运行的话hal会自动加载它,这会导致关机时无法卸载,因此为免麻烦,DAEMONS列表里dbus应该排在hal前面。

注意:有些用户报告说这样设置会出问题。如果你发生问题的话,可以尝试先加载hal 然后才dbus

或者你也可以手动启动hal。以root身份输入以下命令:

# /etc/rc.d/hal start

为了让dbus和hal正常地发挥作用,本地用户必须是opticalstorage 组的成员。要实现这一点,打开终端,以root身份输入以下命令:

# gpasswd -a username
 optical
# gpasswd -a username
 storage

把“username“换成你的用户名(比如johndoe)

你必须完全注销并重新登录,这些用户组设置才会生效。

二、配置

权限策略

程序通过一个D-Bus接口同HAL进行交流。在这里定义很多接口 ,每个相关含有不同方式:存储设备接口,例如,有'弹出设备'和'关闭光驱'。 为了能够'挂载'USB盘上的一个分区,你必须获取相关的D-bus接口(这个地方说的是'卷宗'volume )。

/etc/dbus-1/system.d/hal.conf这个配置文件包含了HAL-specific具体的特权。也就是哪些用户有权力访问哪些接口。/etc/dbus-1/system.conf这个文件内容定义了用在D-bus接口上的例外的策略。简单来说,你需要查看你给用户访问DBUS/HAL接口的权力有哪些,因为D-Bus默认是不会给你任何全权限的。

默认的hal.conf包含了一些允许和拒绝访问的策略,amongst them this default (the later of two defaults and therefore seemingly the deciding one):

File: /etc/dbus-1/system.d/hal.conf
 <!-- Default policy for the exported interfaces -->
 <policy context="default">
   <deny send_interface="org.freedesktop.Hal.Device.SystemPowerManagement"/>
   <deny send_interface="org.freedesktop.Hal.Device.VideoAdapterPM"/>
   <deny send_interface="org.freedesktop.Hal.Device.LaptopPanel"/>
   <deny send_interface="org.freedesktop.Hal.Device.Volume"/>
   <deny send_interface="org.freedesktop.Hal.Device.Volume.Crypto"/>
 </policy>

简单的说,默认设置是用户被拒绝访问如挂载或者卸载卷的接口。下面的策略就是来让'power'和'storage'组用户访问特定设备的:

File: /etc/dbus-1/system.d/hal.conf
 <policy group="power">
   <allow send_interface="org.freedesktop.Hal.Device.SystemPowerManagement"/>
   <allow send_interface="org.freedesktop.Hal.Device.LaptopPanel"/>
 </policy>

 <policy group="storage">
   <allow send_interface="org.freedesktop.Hal.Device.Volume"/>
   <allow send_interface="org.freedesktop.Hal.Device.Volume.Crypto"/>
 </policy>

这就是为什么你需要添加你的用户到这些组的原因(见'初始设置'),这样也可以减少自己设置配置文件的数量。

设备具体策略

NTFS写权限

如果你想在挂载NTFS文件系统时获得写入支持,你必须安装ntfs-3g 然后添加如下内容到 /usr/share/hal/fdi/policy/10osvendor/20-ntfs-config-write-policy.fdi (不存在就新建)

<?xml version="1.0" encoding="UTF-8"?> 
<deviceinfo version="0.2">
   <device>
       <match key="volume.fstype" string="ntfs">
           <match key="@block.storage_device:storage.hotpluggable" bool="true">
               <merge key="volume.fstype" type="string">ntfs-3g</merge>
               <merge key="volume.policy.mount_filesystem" type="string">ntfs-3g</merge>
               <append key="volume.mount.valid_options" type="strlist">locale=</append>
           </match>
       </match>
   </device>
</deviceinfo>

注意:GNOME自2.20版起使用ntfs-3g挂载ntfs分区,因此你不再需要添加这些了。

mount.ntfs链接

对hal>=0.5.10,上面的策略可能不起作用。这里有一个临时的办法可以强制hal使用ntfs-3g而不是标准的ntfs驱动。请注意,这个办法将会使你的系统中所有ntfs驱动器都使用ntfs-3g的驱动!作为root创建一个从mount.ntfs到ntfs-3g的软链接:

# ln -s /sbin/mount.ntfs-3g /sbin/mount.ntfs

这一做法可能引起的问题:

  • 带有“-i“参数的mount命令会失效
  • 可能与内核中的ntfs模块发生冲突

语言问题

Note: 这个问题在ntfs-3g 2009.1.1和更新的版本里不会发生。

如果你的文件名包含非拉丁字符的话可能会有问题。这是挂载程序没有正确地解析这些策略和语言项。以下是解决方案:

  • 移除软链接: rm /sbin/mount.ntfs-3g
  • 把它替换成包含如下内容的bash脚本:
File: /sbin/mount.ntfs-3g
 #!/bin/bash
 /bin/ntfs-3g $1 "$2" -o locale=en_US.UTF-8
,$4  # put your own locale here
  • 使它可执行:chmod +x /sbin/mount.ntfs-3g
  • 添加到 /etc/pacman.conf
File: /etc/pacman.conf
...
 NoUpgrade = sbin/mount.ntfs-3g
...

对可移动设备开启noatime挂载选项

这可以加速文件操作,同时降低闪存设备如U盘、SD卡的损耗.

File: /etc/hal/fdi/policy/20-noatime-removable.fdi
<device> 
  <match key="block.is_volume" bool="true">
    <match key="@block.storage_device:storage.hotpluggable" bool="true">
      <merge key="volume.policy.mount_option.noatime" type="bool">true</merge>
    </match>
    <match key="@block.storage_device:storage.removable" bool="true">
      <merge key="volume.policy.mount_option.noatime" type="bool">true</merge>
    </match>
  </match>
</device>

取消登录时自动挂载

如果要登录时取消自动挂载ntfs或者其它文件系统:

File: /etc/hal/fdi/policy/20-disable-automount.fdi
  <device>
    <match key="storage.hotpluggable" bool="false">
      <match key="storage.removable" bool="false">
        <merge key="storage.automount_enabled_hint" type="bool">false</merge>
      </match>
    </match>
  </device>

重启或启动HAL

要修改生效,需要重启hal

# /etc/rc.d/hal restart

疑难解答

Note: 所有修改需要用/etc/rc.d/hal restart 重启HAL后才生效!

挂载失败

IsCallerPrivileged failed

如果你在没有使用KDM或者GDM的情况下,出现"IsCallerPriviliged failed"提示消息,可以试一下用ck-launch-session (包含在consolekit 软件包)来启动你的DE/WM。

例如对于startx/KDE,~/.xinitrc 中原来的是:

exec startkde

那么新的写法就是:

exec ck-launch-session startkde

无法从Gnome挂在内部驱动器

如果你无法从Gnome挂在内部驱动器(在Nautilus中点击它们),可以打开System -> Preferences下的Authorizations,然后查看org.freedesktop.hal.storage,选择Mount file systems from internal drives,点击Edit,然后将Active Console改为Yes。

权限被拒绝

注意: 解决此问题的另一种方法可见I won the struggle against hal and policykit 。它也有助于纠正掉电和系统关机的问题。

如果你是刚升级到的hal-0.5.11-7,突然出现用非root用户挂载设备发生以下这些错误导致失败:

  • "PermissionDeniedByPolicy mount-removable no"
  • "PermissionDeniedByPolicy mount-removable-extra-options no"
  • "org.freedesktop.hal.storage.mount-removable no <-- (action, result)"
  • "org.freedesktop.hal.storage.mount-removable-extra-options no <-- (action, result)"

可以编辑/etc/PolicyKit/PolicyKit.conf 并粘帖以下内容到<config>段以解决这些问题:

File: /etc/PolicyKit/PolicyKit.conf
<match user="$user
">
<!-- replace with your login or delete the line if you want to allow all users to manipulate devices (keep security issues in mind though) -->
	<match action="org.freedesktop.hal.storage.*">
		<return result="yes"/>
	</match>
	<match action="hal-storage-mount-fixed-extra-options">
	<!-- for internal devices mounted with extra options like a wished mount point -->
		<return result="yes" />
	</match>
	<match action="hal-storage-mount-removable-extra-options">
	<!-- for external devices mounted with extra options like a wished mount point -->
		<return result="yes" />
	</match>
</match> <!-- don't forget to delete this line if you deleted the first one -->

重启dbus和hal。如果你使用KDE的话还要一同重启KDE(否则设备通知器会出问题并停止响应)。作为这类问题的Hotfix这来自于 Gullible Jones的"So long, Arch" 一贴,也许它不是最佳的修复方案(特别是对于很多用户的计算机),不过它的确能行得通。

Note: 请确认你象<match user="myuser"> and NOT like <match user="$myuser"> 这样输入你的用户名。

仍然不行

如果以上方法仍然不行,可以尝试以下“

 <match user="yourusername">
     <return result="yes"/>
 </match>

注意: 这将允许一切!

其它修复方式

如果你从.xinitrc中启动窗口管理器,请看"IsCallerPrivileged failed"中的第2项。

另一种修复方式

File: /etc/PolicyKit/PolicyKit.conf
<config version="0.1">
     <define_admin_auth user="USER"/>
</config>

其中USER是你的用户名。

File: ~.xinitrc
exec ck-launch-session window-manager

这将给予用户特定的管理员权限,它和hal和root用户的hal管理权限一样。

自动挂载失败

插入的CD/DVD不能被hal识别

如果插入的CD/DVD没有被hal识别(桌面上没有图标),检查/etc/fstab ,移除可选驱动器的相关行。

如果不行,这可能是因为你的设备没有被HAl标记为自动挂载。我也不知道这是为什么,不过你可以编辑包含以下内容的/etc/hal/fdi/information/media-check-disable-storage_model_$YOUR_DEVICE .fdi

File: /etc/hal/fdi/information/media-check-disable-storage_model_$YOUR_DEVICE .fdi
 <deviceinfo version="0.2">
   <device>
     <match key="info.udi" string="/org/freedesktop/Hal/devices/storage_model_DV$
       <merge key="storage.media_check_enabled" type="bool">false</merge>
     </match>
   </device>
 </deviceinfo>

如果key设为了false,那么你只需要把它改为true就行了。

USB闪盘/驱动器没有被正确地自动挂载

这段内容来自这个论坛 .

如果你在自动挂载USB闪盘/驱动器时遭遇了麻烦,自动挂载CD、DVD却毫无问题,而且如果你可以手动挂载那些遇到麻烦的USB设备,那么你应该在/etc/hal/fdi/policy中创建一个“preferences.fdi”文件,然后把下面这一行粘贴到文件中:

File: /etc/hal/fdi/policy/preferences.fdi
 <merge key="volume.ignore" type="bool">false</merge>

而且,如果你安装了gparted,可能还需要删除这个文件/usr/share/hal/fdi/policy/gparted-disable-automount.fdi 。在[1] 这个帖子的末尾有人提到这一点。

同时你还得删除/etc/fstab 行中相应的usb设备,hal会自动挂载它们。

移除U盘导致不正常卸载

如果你在没有卸载前移除你的U盘,HAL的自动卸载可能会工作不正常。

你会发现/media/.hal-mtab 中相应的记录没有被删除,并且nautilus的设备列表(还有GNOME的桌面)会保留了指向设备曾经挂载过的空文件夹的链接。

这些都可以通过用延迟参数卸载U盘来解决。只要这么做:

1) 创建访问权限755的可执行脚本/usr/lib/hal/hal-unmount.sh ,内容如下:

File: /usr/lib/hal/hal-unmount.sh
 #!/bin/sh 
 # sanity check. DEVNAME should start with a / 
 [ "$DEVNAME" != "${DEVNAME#/}" ] || exit 0
 # Lazily unmount drives which are removed, but still mounted 
 if [ "$ACTION" = remove ] ; then
   if [ -x /usr/bin/pumount ] ; then
     /usr/bin/pumount -l "$DEVNAME";
   else
     /bin/umount -l "$DEVNAME";
   fi
 fi
 exit 0

2) 然后你得告诉HAL当你移除你的U盘时运行这个脚本。在/etc/udev/rules.d/90-hal.rules 中加入以下内容:

File: /etc/udev/rules.d/90-hal.rules
 SUBSYSTEM=="block", ACTION=="remove", RUN+="/usr/lib/hal/hal-unmount.sh"

3) 执行重启

# /etc/rc.d/hal restart
http://socol.javaeye.com/blog/518911
原文地址:https://www.cnblogs.com/chenxuelian/p/1700354.html