Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The difference between vold and udevd

I knew that Android uses volume daemon instead of udevd.

Since both of these two daemons act similar as the following:

  1. Use netlink socket to receive uevents sent from kernel.

  2. Deals with file nodes for further processing.

I am not clear with the difference between these two different daemons.

Can someone provide feedback? It will be great with pros and cons.

Thanks

like image 867
Sam Avatar asked May 05 '14 07:05

Sam


People also ask

What is vold in android?

The vold [short for Volume Daemon] is the service responsible for detecting and mounting/unmounting of all the external or extended storage media in Android like usb, sdcard, cdrom. Its main function involves in helping Android support hot pluggable storage devices.

What does udev do?

udev is a replacement for the Device File System (DevFS) starting with the Linux 2.6 kernel series. It allows you to identify devices based on their properties, like vendor ID and device ID, dynamically. udev runs in userspace (as opposed to devfs which was executed in kernel space).

What is Uevent?

uevent is just string of some special format that is sent via netlink socket.

What are udev rules?

Udev rules determine how to identify devices and how to assign a name that is persistent through reboots or disk changes. When Udev receives a device event, it matches the configured rules against the device attributes in sysfs to identify the device.


1 Answers

After looking at vold source code I can only tell that it's just a simple replacement for udevd.

You're right that vold is using netlink socket to receive uevents from kernel. But I'd say that it deals with block subsystem events rather than "file nodes" as you say.

In NetlinkHandler.cpp you can see the following:

void NetlinkHandler::onEvent(NetlinkEvent *evt) {
    VolumeManager *vm = VolumeManager::Instance();
    const char *subsys = evt->getSubsystem();

    if (!subsys) {
        SLOGW("No subsystem found in netlink event");
        return;
    }

    if (!strcmp(subsys, "block")) {
        vm->handleBlockEvent(evt);
    }
}

Last lines just compare uevent subsystem string with "block". And that is the main difference from udevd a far as I can see because udevd handles all subsystems whereas vold is a simple daemon to handle block devices like memory cards.

Good presentation on vold: http://www.slideshare.net/wiliwe/android-storage-vold

EDIT on subsystems

A subsystem is a representation for a high-level portion of the kernel as a whole. Actually, subsystem is just a wrapper on kernel's kset. There is a nice writing about it in LDD3, chapter 14.1 - Kobjects, Ksets, and Subsystems.

For example, let's monitor events when I insert USB stick.

$ udevadm monitor -k
KERNEL[82215.299677] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1 (usb)
KERNEL[82215.299921] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0 (usb)
KERNEL[82215.300192] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/host10 (scsi)
KERNEL[82215.300226] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/host10/scsi_host/host10 (scsi_host)
KERNEL[82216.339987] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/host10/target10:0:0 (scsi)
KERNEL[82216.340047] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/host10/target10:0:0/10:0:0:0 (scsi)
KERNEL[82216.340069] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/host10/target10:0:0/10:0:0:0/scsi_disk/10:0:0:0 (scsi_disk)
KERNEL[82216.340088] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/host10/target10:0:0/10:0:0:0/scsi_device/10:0:0:0 (scsi_device)
KERNEL[82216.340302] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/host10/target10:0:0/10:0:0:0/scsi_generic/sg2 (scsi_generic)
KERNEL[82216.340445] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/host10/target10:0:0/10:0:0:0/bsg/10:0:0:0 (bsg)
KERNEL[82217.110295] add      /devices/virtual/bdi/8:16 (bdi)
KERNEL[82217.141629] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/host10/target10:0:0/10:0:0:0/block/sdb (block)

To determine what is subsystem in this output let's look at udev code in udevadm-monitor.c

static void print_device(struct udev_device *device, const char *source, int prop)
{
        struct timespec ts;

        clock_gettime(CLOCK_MONOTONIC, &ts);
        printf("%-6s[%llu.%06u] %-8s %s (%s)\n",
               source,
               (unsigned long long) ts.tv_sec, (unsigned int) ts.tv_nsec/1000,
               udev_device_get_action(device),
               udev_device_get_devpath(device),
               udev_device_get_subsystem(device));
        if (prop) {
                struct udev_list_entry *list_entry;

                udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
                        printf("%s=%s\n",
                               udev_list_entry_get_name(list_entry),
                               udev_list_entry_get_value(list_entry));
                printf("\n");
        }
}

In first printf, udev_device_get_subsystem(device) will output sybsystem in last field in parenthesis.

So for udevadm monitor output you can see the following subsystems:

  • usb
  • scsi
  • scsi_host
  • scsi_disk
  • scsi_device
  • scsi_generic
  • bsg
  • bdi
  • block

udev will handle all of this events to create different entries under /dev, for example

  • /dev/disk/by-id/<entry> will be created based on disk SCSI WWN
  • /dev/disk/by-path/<entry> will be created based on PCI connections and SCSI host info.
  • and so on

In contrast, vold only interested in uevents from block sybsystem, it does not care about scsi, usb or bdi stuff.

like image 91
Alexander Dzyoba Avatar answered Nov 04 '22 18:11

Alexander Dzyoba