سؤال

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

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

In android there is no udevd, it is called as ueventsd . Both Ueventsd and vold is present in android. Vold is for removalbale storages mainly sdcard, pendrive etc.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top