LCOV - code coverage report
Current view: top level - udev - udev-builtin-blkid.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 0 164 0.0 %
Date: 2019-08-22 15:41:25 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0+ */
       2             : /*
       3             :  * probe disks for filesystems and partitions
       4             :  *
       5             :  * Copyright © 2011 Karel Zak <kzak@redhat.com>
       6             :  */
       7             : 
       8             : #include <blkid.h>
       9             : #include <errno.h>
      10             : #include <fcntl.h>
      11             : #include <getopt.h>
      12             : #include <stdio.h>
      13             : #include <stdlib.h>
      14             : #include <string.h>
      15             : #include <sys/stat.h>
      16             : 
      17             : #include "sd-id128.h"
      18             : 
      19             : #include "alloc-util.h"
      20             : #include "blkid-util.h"
      21             : #include "device-util.h"
      22             : #include "efivars.h"
      23             : #include "errno-util.h"
      24             : #include "fd-util.h"
      25             : #include "gpt.h"
      26             : #include "parse-util.h"
      27             : #include "string-util.h"
      28             : #include "strxcpyx.h"
      29             : #include "udev-builtin.h"
      30             : 
      31           0 : static void print_property(sd_device *dev, bool test, const char *name, const char *value) {
      32             :         char s[256];
      33             : 
      34           0 :         s[0] = '\0';
      35             : 
      36           0 :         if (streq(name, "TYPE")) {
      37           0 :                 udev_builtin_add_property(dev, test, "ID_FS_TYPE", value);
      38             : 
      39           0 :         } else if (streq(name, "USAGE")) {
      40           0 :                 udev_builtin_add_property(dev, test, "ID_FS_USAGE", value);
      41             : 
      42           0 :         } else if (streq(name, "VERSION")) {
      43           0 :                 udev_builtin_add_property(dev, test, "ID_FS_VERSION", value);
      44             : 
      45           0 :         } else if (streq(name, "UUID")) {
      46           0 :                 blkid_safe_string(value, s, sizeof(s));
      47           0 :                 udev_builtin_add_property(dev, test, "ID_FS_UUID", s);
      48           0 :                 blkid_encode_string(value, s, sizeof(s));
      49           0 :                 udev_builtin_add_property(dev, test, "ID_FS_UUID_ENC", s);
      50             : 
      51           0 :         } else if (streq(name, "UUID_SUB")) {
      52           0 :                 blkid_safe_string(value, s, sizeof(s));
      53           0 :                 udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB", s);
      54           0 :                 blkid_encode_string(value, s, sizeof(s));
      55           0 :                 udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB_ENC", s);
      56             : 
      57           0 :         } else if (streq(name, "LABEL")) {
      58           0 :                 blkid_safe_string(value, s, sizeof(s));
      59           0 :                 udev_builtin_add_property(dev, test, "ID_FS_LABEL", s);
      60           0 :                 blkid_encode_string(value, s, sizeof(s));
      61           0 :                 udev_builtin_add_property(dev, test, "ID_FS_LABEL_ENC", s);
      62             : 
      63           0 :         } else if (streq(name, "PTTYPE")) {
      64           0 :                 udev_builtin_add_property(dev, test, "ID_PART_TABLE_TYPE", value);
      65             : 
      66           0 :         } else if (streq(name, "PTUUID")) {
      67           0 :                 udev_builtin_add_property(dev, test, "ID_PART_TABLE_UUID", value);
      68             : 
      69           0 :         } else if (streq(name, "PART_ENTRY_NAME")) {
      70           0 :                 blkid_encode_string(value, s, sizeof(s));
      71           0 :                 udev_builtin_add_property(dev, test, "ID_PART_ENTRY_NAME", s);
      72             : 
      73           0 :         } else if (streq(name, "PART_ENTRY_TYPE")) {
      74           0 :                 blkid_encode_string(value, s, sizeof(s));
      75           0 :                 udev_builtin_add_property(dev, test, "ID_PART_ENTRY_TYPE", s);
      76             : 
      77           0 :         } else if (startswith(name, "PART_ENTRY_")) {
      78           0 :                 strscpyl(s, sizeof(s), "ID_", name, NULL);
      79           0 :                 udev_builtin_add_property(dev, test, s, value);
      80             : 
      81           0 :         } else if (streq(name, "SYSTEM_ID")) {
      82           0 :                 blkid_encode_string(value, s, sizeof(s));
      83           0 :                 udev_builtin_add_property(dev, test, "ID_FS_SYSTEM_ID", s);
      84             : 
      85           0 :         } else if (streq(name, "PUBLISHER_ID")) {
      86           0 :                 blkid_encode_string(value, s, sizeof(s));
      87           0 :                 udev_builtin_add_property(dev, test, "ID_FS_PUBLISHER_ID", s);
      88             : 
      89           0 :         } else if (streq(name, "APPLICATION_ID")) {
      90           0 :                 blkid_encode_string(value, s, sizeof(s));
      91           0 :                 udev_builtin_add_property(dev, test, "ID_FS_APPLICATION_ID", s);
      92             : 
      93           0 :         } else if (streq(name, "BOOT_SYSTEM_ID")) {
      94           0 :                 blkid_encode_string(value, s, sizeof(s));
      95           0 :                 udev_builtin_add_property(dev, test, "ID_FS_BOOT_SYSTEM_ID", s);
      96             :         }
      97           0 : }
      98             : 
      99           0 : static int find_gpt_root(sd_device *dev, blkid_probe pr, bool test) {
     100             : 
     101             : #if defined(GPT_ROOT_NATIVE) && ENABLE_EFI
     102             : 
     103           0 :         _cleanup_free_ char *root_id = NULL;
     104           0 :         bool found_esp = false;
     105             :         blkid_partlist pl;
     106             :         int i, nvals, r;
     107             : 
     108           0 :         assert(pr);
     109             : 
     110             :         /* Iterate through the partitions on this disk, and see if the
     111             :          * EFI ESP we booted from is on it. If so, find the first root
     112             :          * disk, and add a property indicating its partition UUID. */
     113             : 
     114           0 :         errno = 0;
     115           0 :         pl = blkid_probe_get_partitions(pr);
     116           0 :         if (!pl)
     117           0 :                 return errno_or_else(ENOMEM);
     118             : 
     119           0 :         nvals = blkid_partlist_numof_partitions(pl);
     120           0 :         for (i = 0; i < nvals; i++) {
     121             :                 blkid_partition pp;
     122             :                 const char *stype, *sid;
     123             :                 sd_id128_t type;
     124             : 
     125           0 :                 pp = blkid_partlist_get_partition(pl, i);
     126           0 :                 if (!pp)
     127           0 :                         continue;
     128             : 
     129           0 :                 sid = blkid_partition_get_uuid(pp);
     130           0 :                 if (!sid)
     131           0 :                         continue;
     132             : 
     133           0 :                 stype = blkid_partition_get_type_string(pp);
     134           0 :                 if (!stype)
     135           0 :                         continue;
     136             : 
     137           0 :                 if (sd_id128_from_string(stype, &type) < 0)
     138           0 :                         continue;
     139             : 
     140           0 :                 if (sd_id128_equal(type, GPT_ESP)) {
     141             :                         sd_id128_t id, esp;
     142             : 
     143             :                         /* We found an ESP, let's see if it matches
     144             :                          * the ESP we booted from. */
     145             : 
     146           0 :                         if (sd_id128_from_string(sid, &id) < 0)
     147           0 :                                 continue;
     148             : 
     149           0 :                         r = efi_loader_get_device_part_uuid(&esp);
     150           0 :                         if (r < 0)
     151           0 :                                 return r;
     152             : 
     153           0 :                         if (sd_id128_equal(id, esp))
     154           0 :                                 found_esp = true;
     155             : 
     156           0 :                 } else if (sd_id128_equal(type, GPT_ROOT_NATIVE)) {
     157             :                         unsigned long long flags;
     158             : 
     159           0 :                         flags = blkid_partition_get_flags(pp);
     160           0 :                         if (flags & GPT_FLAG_NO_AUTO)
     161           0 :                                 continue;
     162             : 
     163             :                         /* We found a suitable root partition, let's
     164             :                          * remember the first one. */
     165             : 
     166           0 :                         if (!root_id) {
     167           0 :                                 root_id = strdup(sid);
     168           0 :                                 if (!root_id)
     169           0 :                                         return -ENOMEM;
     170             :                         }
     171             :                 }
     172             :         }
     173             : 
     174             :         /* We found the ESP on this disk, and also found a root
     175             :          * partition, nice! Let's export its UUID */
     176           0 :         if (found_esp && root_id)
     177           0 :                 udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT_UUID", root_id);
     178             : #endif
     179             : 
     180           0 :         return 0;
     181             : }
     182             : 
     183           0 : static int probe_superblocks(blkid_probe pr) {
     184             :         struct stat st;
     185             :         int rc;
     186             : 
     187             :         /* TODO: Return negative errno. */
     188             : 
     189           0 :         if (fstat(blkid_probe_get_fd(pr), &st))
     190           0 :                 return -errno;
     191             : 
     192           0 :         blkid_probe_enable_partitions(pr, 1);
     193             : 
     194           0 :         if (!S_ISCHR(st.st_mode) &&
     195           0 :             blkid_probe_get_size(pr) <= 1024 * 1440 &&
     196           0 :             blkid_probe_is_wholedisk(pr)) {
     197             :                 /*
     198             :                  * check if the small disk is partitioned, if yes then
     199             :                  * don't probe for filesystems.
     200             :                  */
     201           0 :                 blkid_probe_enable_superblocks(pr, 0);
     202             : 
     203           0 :                 rc = blkid_do_fullprobe(pr);
     204           0 :                 if (rc < 0)
     205           0 :                         return rc;        /* -1 = error, 1 = nothing, 0 = success */
     206             : 
     207           0 :                 if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0)
     208           0 :                         return 0;        /* partition table detected */
     209             :         }
     210             : 
     211           0 :         blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
     212           0 :         blkid_probe_enable_superblocks(pr, 1);
     213             : 
     214           0 :         return blkid_do_safeprobe(pr);
     215             : }
     216             : 
     217           0 : static int builtin_blkid(sd_device *dev, int argc, char *argv[], bool test) {
     218           0 :         const char *devnode, *root_partition = NULL, *data, *name;
     219           0 :         _cleanup_(blkid_free_probep) blkid_probe pr = NULL;
     220           0 :         bool noraid = false, is_gpt = false;
     221           0 :         _cleanup_close_ int fd = -1;
     222           0 :         int64_t offset = 0;
     223             :         int nvals, i, r;
     224             : 
     225             :         static const struct option options[] = {
     226             :                 { "offset", required_argument, NULL, 'o' },
     227             :                 { "noraid", no_argument, NULL, 'R' },
     228             :                 {}
     229             :         };
     230             : 
     231           0 :         for (;;) {
     232             :                 int option;
     233             : 
     234           0 :                 option = getopt_long(argc, argv, "o:R", options, NULL);
     235           0 :                 if (option == -1)
     236           0 :                         break;
     237             : 
     238           0 :                 switch (option) {
     239           0 :                 case 'o':
     240           0 :                         r = safe_atoi64(optarg, &offset);
     241           0 :                         if (r < 0)
     242           0 :                                 return log_device_error_errno(dev, r, "Failed to parse '%s' as an integer: %m", optarg);
     243           0 :                         if (offset < 0)
     244           0 :                                 return log_device_error_errno(dev, SYNTHETIC_ERRNO(ERANGE), "Invalid offset %"PRIi64": %m", offset);
     245           0 :                         break;
     246           0 :                 case 'R':
     247           0 :                         noraid = true;
     248           0 :                         break;
     249             :                 }
     250           0 :         }
     251             : 
     252           0 :         errno = 0;
     253           0 :         pr = blkid_new_probe();
     254           0 :         if (!pr)
     255           0 :                 return log_device_debug_errno(dev, errno > 0 ? errno : ENOMEM, "Failed to create blkid prober: %m");
     256             : 
     257           0 :         blkid_probe_set_superblocks_flags(pr,
     258             :                 BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
     259             :                 BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
     260             :                 BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);
     261             : 
     262           0 :         if (noraid)
     263           0 :                 blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID);
     264             : 
     265           0 :         r = sd_device_get_devname(dev, &devnode);
     266           0 :         if (r < 0)
     267           0 :                 return log_device_debug_errno(dev, r, "Failed to get device name: %m");
     268             : 
     269           0 :         fd = open(devnode, O_RDONLY|O_CLOEXEC);
     270           0 :         if (fd < 0)
     271           0 :                 return log_device_debug_errno(dev, errno, "Failed to open block device %s: %m", devnode);
     272             : 
     273           0 :         errno = 0;
     274           0 :         r = blkid_probe_set_device(pr, fd, offset, 0);
     275           0 :         if (r < 0)
     276           0 :                 return log_device_debug_errno(dev, errno > 0 ? errno : ENOMEM, "Failed to set device to blkid prober: %m");
     277             : 
     278           0 :         log_device_debug(dev, "Probe %s with %sraid and offset=%"PRIi64, devnode, noraid ? "no" : "", offset);
     279             : 
     280           0 :         r = probe_superblocks(pr);
     281           0 :         if (r < 0)
     282           0 :                 return log_device_debug_errno(dev, r, "Failed to probe superblocks: %m");
     283             : 
     284             :         /* If the device is a partition then its parent passed the root partition UUID to the device */
     285           0 :         (void) sd_device_get_property_value(dev, "ID_PART_GPT_AUTO_ROOT_UUID", &root_partition);
     286             : 
     287           0 :         errno = 0;
     288           0 :         nvals = blkid_probe_numof_values(pr);
     289           0 :         if (nvals < 0)
     290           0 :                 return log_device_debug_errno(dev, errno > 0 ? errno : ENOMEM, "Failed to get number of probed values: %m");
     291             : 
     292           0 :         for (i = 0; i < nvals; i++) {
     293           0 :                 if (blkid_probe_get_value(pr, i, &name, &data, NULL) < 0)
     294           0 :                         continue;
     295             : 
     296           0 :                 print_property(dev, test, name, data);
     297             : 
     298             :                 /* Is this a disk with GPT partition table? */
     299           0 :                 if (streq(name, "PTTYPE") && streq(data, "gpt"))
     300           0 :                         is_gpt = true;
     301             : 
     302             :                 /* Is this a partition that matches the root partition
     303             :                  * property inherited from the parent? */
     304           0 :                 if (root_partition && streq(name, "PART_ENTRY_UUID") && streq(data, root_partition))
     305           0 :                         udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT", "1");
     306             :         }
     307             : 
     308           0 :         if (is_gpt)
     309           0 :                 find_gpt_root(dev, pr, test);
     310             : 
     311           0 :         return 0;
     312             : }
     313             : 
     314             : const UdevBuiltin udev_builtin_blkid = {
     315             :         .name = "blkid",
     316             :         .cmd = builtin_blkid,
     317             :         .help = "Filesystem and partition probing",
     318             :         .run_once = true,
     319             : };

Generated by: LCOV version 1.14