LCOV - code coverage report
Current view: top level - udev - udev-builtin-blkid.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 164 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 4 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 177 0.0 %

           Branch data     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