Coverage Report

Created: 2025-11-11 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/util-linux/libblkid/src/topology/dm.c
Line
Count
Source
1
/*
2
 * device-mapper (dm) topology
3
 * -- this is fallback for old systems where the topology information is not
4
 *    exported by sysfs
5
 *
6
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
7
 *
8
 * This file may be redistributed under the terms of the
9
 * GNU Lesser General Public License.
10
 *
11
 */
12
#include <errno.h>
13
#include <fcntl.h>
14
#include <stdint.h>
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <string.h>
18
#include <sys/stat.h>
19
#include <sys/types.h>
20
#include <unistd.h>
21
22
#include "topology.h"
23
24
static int is_dm_device(dev_t devno)
25
0
{
26
0
  return blkid_driver_has_major("device-mapper", major(devno));
27
0
}
28
29
static int probe_dm_tp(blkid_probe pr,
30
    const struct blkid_idmag *mag __attribute__((__unused__)))
31
0
{
32
0
  const char * const paths[] = {
33
0
    "/usr/local/sbin/dmsetup",
34
0
    "/usr/sbin/dmsetup",
35
0
    "/sbin/dmsetup"
36
0
  };
37
0
  int dmpipe[] = { -1, -1 }, stripes = 0, stripesize = 0;
38
0
  const char *cmd = NULL;
39
0
  FILE *stream = NULL;
40
0
  long long  offset = 0, size = 0;
41
0
  size_t i;
42
0
  dev_t devno = blkid_probe_get_devno(pr);
43
44
0
  if (!devno)
45
0
    goto nothing;   /* probably not a block device */
46
0
  if (!is_dm_device(devno))
47
0
    goto nothing;
48
49
0
  for (i = 0; i < ARRAY_SIZE(paths); i++) {
50
0
    struct stat sb;
51
0
    if (stat(paths[i], &sb) == 0) {
52
0
      cmd = paths[i];
53
0
      break;
54
0
    }
55
0
  }
56
57
0
  if (!cmd)
58
0
    goto nothing;
59
0
  if (pipe(dmpipe) < 0) {
60
0
    DBG(LOWPROBE, ul_debug("Failed to open pipe: errno=%d", errno));
61
0
    goto nothing;
62
0
  }
63
64
0
  switch (fork()) {
65
0
  case 0:
66
0
  {
67
0
    const char *dmargv[7];
68
0
          char maj[16], min[16];
69
70
    /* Plumbing */
71
0
    close(dmpipe[0]);
72
73
0
    if (dmpipe[1] != STDOUT_FILENO)
74
0
      dup2(dmpipe[1], STDOUT_FILENO);
75
76
0
    if (drop_permissions() != 0)
77
0
       _exit(1);
78
79
0
    snprintf(maj, sizeof(maj), "%d", major(devno));
80
0
    snprintf(min, sizeof(min), "%d", minor(devno));
81
82
0
    dmargv[0] = cmd;
83
0
    dmargv[1] = "table";
84
0
    dmargv[2] = "-j";
85
0
    dmargv[3] = maj;
86
0
    dmargv[4] = "-m";
87
0
    dmargv[5] = min;
88
0
    dmargv[6] = NULL;
89
90
0
    execv(dmargv[0], (char * const *) dmargv);
91
92
0
    DBG(LOWPROBE, ul_debug("Failed to execute %s: errno=%d", cmd, errno));
93
0
    exit(1);
94
0
  }
95
0
  case -1:
96
0
    DBG(LOWPROBE, ul_debug("Failed to forking: errno=%d", errno));
97
0
    goto nothing;
98
0
  default:
99
0
    break;
100
0
  }
101
102
0
  stream = fdopen(dmpipe[0], "r" UL_CLOEXECSTR);
103
0
  if (!stream)
104
0
    goto nothing;
105
106
0
  if (dmpipe[1] != -1) {
107
0
    close(dmpipe[1]);
108
0
  }
109
110
0
  if (fscanf(stream, "%lld %lld striped %d %d ",
111
0
      &offset, &size, &stripes, &stripesize) != 4)
112
0
    goto nothing;
113
114
0
  blkid_topology_set_minimum_io_size(pr, stripesize << 9);
115
0
  blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 9);
116
117
0
  fclose(stream);
118
0
  return 0;
119
120
0
nothing:
121
0
  if (stream)
122
0
    fclose(stream);
123
0
  else if (dmpipe[0] != -1)
124
0
    close(dmpipe[0]);
125
0
  return 1;
126
0
}
127
128
const struct blkid_idinfo dm_tp_idinfo =
129
{
130
  .name   = "dm",
131
  .probefunc  = probe_dm_tp,
132
  .magics   = BLKID_NONE_MAGIC
133
};
134