Coverage Report

Created: 2026-08-12 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/lvm2/libdm/ioctl/libdm-iface.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3
 * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
4
 *
5
 * This file is part of the device-mapper userspace tools.
6
 *
7
 * This copyrighted material is made available to anyone wishing to use,
8
 * modify, copy, or redistribute it subject to the terms and conditions
9
 * of the GNU Lesser General Public License v.2.1.
10
 *
11
 * You should have received a copy of the GNU Lesser General Public License
12
 * along with this program; if not, write to the Free Software Foundation,
13
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
 */
15
16
#include "libdm/misc/dmlib.h"
17
#include "libdm-targets.h"
18
#include "libdm/libdm-common.h"
19
20
#include <stddef.h>
21
#include <fcntl.h>
22
#include <dirent.h>
23
#include <pthread.h>
24
#include <sys/ioctl.h>
25
#include <sys/utsname.h>
26
#include <limits.h>
27
28
#ifdef __linux__
29
#  include "libdm/misc/kdev_t.h"
30
#  include <linux/limits.h>
31
#else
32
#  define MAJOR(x) major((x))
33
#  define MINOR(x) minor((x))
34
#  define MKDEV(x,y) makedev(((dev_t)x),((dev_t)y))
35
#endif
36
37
#include "libdm/misc/dm-ioctl.h"
38
39
/*
40
 * Ensure build compatibility.
41
 * The hard-coded versions here are the highest present
42
 * in the _cmd_data arrays.
43
 */
44
45
#if !((DM_VERSION_MAJOR == 4 && DM_VERSION_MINOR >= 6))
46
#error The version of dm-ioctl.h included is incompatible.
47
#endif
48
49
/* FIXME This should be exported in device-mapper.h */
50
0
#define DM_NAME "device-mapper"
51
52
0
#define PROC_MISC "/proc/misc"
53
0
#define PROC_DEVICES "/proc/devices"
54
0
#define MISC_NAME "misc"
55
56
0
#define NUMBER_OF_MAJORS 4096
57
58
/*
59
 * Static minor number assigned since kernel version 2.6.36.
60
 * The original definition is in kernel's include/linux/miscdevice.h.
61
 * This number is also visible in modules.devname exported by depmod
62
 * utility (support included in module-init-tools version >= 3.12).
63
 */
64
0
#define MAPPER_CTRL_MINOR 236
65
0
#define MISC_MAJOR 10
66
67
/* dm major version no for running kernel */
68
static unsigned _dm_version = DM_VERSION_MAJOR;
69
static unsigned _dm_version_minor = 0;
70
static unsigned _dm_version_patchlevel = 0;
71
static int _dm_warn_inactive_suppress = 0;
72
73
/*
74
 * If the kernel dm driver only supports one major number
75
 * we store it in _dm_device_major.  Otherwise we indicate
76
 * which major numbers have been claimed by device-mapper
77
 * in _dm_bitset.
78
 */
79
static unsigned _dm_multiple_major_support = 1;
80
static dm_bitset_t _dm_bitset = NULL;
81
static uint32_t _dm_device_major = 0;
82
83
static int _control_fd = -1;
84
static int _hold_control_fd_open = 0;
85
/* Mutex, not pthread_once: fd can be closed and reopened */
86
static pthread_mutex_t _control_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
87
static int _version_ok = 1;
88
static pthread_once_t _version_once = PTHREAD_ONCE_INIT;
89
static unsigned _ioctl_buffer_double_factor = 0;
90
/* Max ioctl buffer: 16KB << 16 = 1GB */
91
0
#define DM_IOCTL_BUFFER_MAX_DOUBLINGS 16
92
93
/* *INDENT-OFF* */
94
static const struct cmd_data _cmd_data_v4[] = {
95
  {"create",  DM_DEV_CREATE,    {4, 0, 0}},
96
  {"reload",  DM_TABLE_LOAD,    {4, 0, 0}},
97
  {"remove",  DM_DEV_REMOVE,    {4, 0, 0}},
98
  {"remove_all",  DM_REMOVE_ALL,    {4, 0, 0}},
99
  {"suspend", DM_DEV_SUSPEND,   {4, 0, 0}},
100
  {"resume",  DM_DEV_SUSPEND,   {4, 0, 0}},
101
  {"info",  DM_DEV_STATUS,    {4, 0, 0}},
102
  {"deps",  DM_TABLE_DEPS,    {4, 0, 0}},
103
  {"rename",  DM_DEV_RENAME,    {4, 0, 0}},
104
  {"version", DM_VERSION,   {4, 0, 0}},
105
  {"status",  DM_TABLE_STATUS,  {4, 0, 0}},
106
  {"table", DM_TABLE_STATUS,  {4, 0, 0}},
107
  {"waitevent", DM_DEV_WAIT,    {4, 0, 0}},
108
  {"names", DM_LIST_DEVICES,  {4, 0, 0}},
109
  {"clear", DM_TABLE_CLEAR,   {4, 0, 0}},
110
  {"mknodes", DM_DEV_STATUS,    {4, 0, 0}},
111
#ifdef DM_LIST_VERSIONS
112
  {"versions",  DM_LIST_VERSIONS, {4, 1, 0}},
113
#endif
114
#ifdef DM_TARGET_MSG
115
  {"message", DM_TARGET_MSG,    {4, 2, 0}},
116
#endif
117
#ifdef DM_DEV_SET_GEOMETRY
118
  {"setgeometry", DM_DEV_SET_GEOMETRY,  {4, 6, 0}},
119
#endif
120
#ifdef DM_DEV_ARM_POLL
121
  {"armpoll", DM_DEV_ARM_POLL,  {4, 36, 0}},
122
#endif
123
#ifdef DM_GET_TARGET_VERSION
124
  {"target-version", DM_GET_TARGET_VERSION, {4, 41, 0}},
125
#endif
126
};
127
/* *INDENT-ON* */
128
129
/* Validate task type against the command table. */
130
static int _validate_task_type(struct dm_task *dmt)
131
0
{
132
0
  if ((unsigned) dmt->type >= DM_ARRAY_SIZE(_cmd_data_v4)) {
133
0
    log_error(INTERNAL_ERROR "unknown device-mapper task %d",
134
0
        dmt->type);
135
0
    return 0;
136
0
  }
137
138
0
  return 1;
139
0
}
140
141
0
#define ALIGNMENT 8
142
143
/* FIXME Rejig library to record & use errno instead */
144
#ifndef DM_EXISTS_FLAG
145
0
#  define DM_EXISTS_FLAG 0x00000004
146
#endif
147
148
static char *_align(char *ptr, unsigned int a)
149
0
{
150
0
  register unsigned long agn = --a;
151
152
0
  return (char *) (((unsigned long) ptr + agn) & ~agn);
153
0
}
154
155
static unsigned _kernel_major = 0;
156
static unsigned _kernel_minor = 0;
157
static unsigned _kernel_release = 0;
158
static pthread_once_t _uname_once = PTHREAD_ONCE_INIT;
159
160
static void _init_uname(void)
161
0
{
162
0
  struct utsname uts;
163
0
  int parts;
164
165
0
  if (uname(&uts)) {
166
0
    log_sys_error("uname", "");
167
0
    _kernel_major = 0;
168
0
    return;
169
0
  }
170
171
0
  parts = sscanf(uts.release, "%u.%u.%u",
172
0
           &_kernel_major, &_kernel_minor, &_kernel_release);
173
174
  /* Kernels with a major number of 2 always had 3 parts. */
175
0
  if (parts < 1 || (_kernel_major < 3 && parts < 3)) {
176
0
    _kernel_major = 0;
177
0
    return;
178
0
  }
179
0
}
180
181
static int _uname(void)
182
0
{
183
0
  pthread_once(&_uname_once, _init_uname);
184
185
0
  if (!_kernel_major) {
186
0
    log_error("Could not determine kernel version used.");
187
0
    return 0;
188
0
  }
189
190
0
  return 1;
191
0
}
192
193
int get_uname_version(unsigned *major, unsigned *minor, unsigned *release)
194
0
{
195
0
  if (!_uname())
196
0
    return_0;
197
198
0
  *major = _kernel_major;
199
0
  *minor = _kernel_minor;
200
0
  *release = _kernel_release;
201
202
0
  return 1;
203
0
}
204
205
#ifdef DM_IOCTLS
206
207
/*
208
 * Set number to NULL to populate _dm_bitset - otherwise first
209
 * match is returned.
210
 * Returns:
211
 *  0 - error
212
 *  1 - success - number found
213
 *  2 - success - number not found (only if require_module_loaded=0)
214
 */
215
static int _get_proc_number(const char *file, const char *name,
216
          uint32_t *number, int require_module_loaded)
217
0
{
218
0
  FILE *fl;
219
0
  char nm[256];
220
0
  char *line = NULL;
221
0
  size_t len;
222
0
  uint32_t num;
223
0
  unsigned blocksection = (strcmp(file, PROC_DEVICES) == 0) ? 0 : 1;
224
225
0
  if (!(fl = fopen(file, "r"))) {
226
0
    log_sys_error("fopen", file);
227
0
    return 0;
228
0
  }
229
230
0
  while (getline(&line, &len, fl) != -1) {
231
0
    if (!blocksection && (line[0] == 'B'))
232
0
      blocksection = 1;
233
0
    else if (sscanf(line, "%u %255s\n", &num, &nm[0]) == 2) {
234
0
      if (!strcmp(name, nm)) {
235
0
        if (number) {
236
0
          *number = num;
237
0
          if (fclose(fl))
238
0
            log_sys_error("fclose", file);
239
0
          free(line);
240
0
          return 1;
241
0
        }
242
0
        dm_bit_set(_dm_bitset, num);
243
0
      }
244
0
    }
245
0
  }
246
0
  if (fclose(fl))
247
0
    log_sys_error("fclose", file);
248
0
  free(line);
249
250
0
  if (number) {
251
0
    if (require_module_loaded) {
252
0
      log_error("%s: No entry for %s found", file, name);
253
0
      return 0;
254
0
    }
255
256
0
    return 2;
257
0
  }
258
259
0
  return 1;
260
0
}
261
262
static int _control_device_number(uint32_t *major, uint32_t *minor)
263
0
{
264
0
  if (!_get_proc_number(PROC_DEVICES, MISC_NAME, major, 1) ||
265
0
      !_get_proc_number(PROC_MISC, DM_NAME, minor, 1)) {
266
0
    *major = 0;
267
0
    return 0;
268
0
  }
269
270
0
  return 1;
271
0
}
272
273
static int _control_unlink(const char *control)
274
0
{
275
0
  if (unlink(control) && (errno != ENOENT)) {
276
0
    log_sys_error("unlink", control);
277
0
    return -1;
278
0
  }
279
280
0
  return 0;
281
0
}
282
283
/*
284
 * Returns 1 if it exists on returning; 0 if it doesn't; -1 if it's wrong.
285
 */
286
static int _control_exists(const char *control, uint32_t major, uint32_t minor)
287
0
{
288
0
  struct stat buf;
289
290
0
  if (stat(control, &buf) < 0) {
291
0
    if (errno != ENOENT)
292
0
      log_sys_error("stat", control);
293
0
    return 0;
294
0
  }
295
296
0
  if (!S_ISCHR(buf.st_mode)) {
297
0
    log_verbose("%s: Wrong inode type", control);
298
0
    return _control_unlink(control);
299
0
  }
300
301
0
  if (major && buf.st_rdev != MKDEV(major, minor)) {
302
0
    log_verbose("%s: Wrong device number: (%u, %u) instead of "
303
0
          "(%u, %u).", control,
304
0
          MAJOR(buf.st_rdev), MINOR(buf.st_rdev),
305
0
          major, minor);
306
0
    return _control_unlink(control);
307
0
  }
308
309
0
  return 1;
310
0
}
311
312
static int _create_control(const char *control, uint32_t major, uint32_t minor)
313
0
{
314
0
  int ret;
315
0
  mode_t old_umask;
316
317
  /*
318
   * Return if the control already exists with intended major/minor
319
   * or there's an error unlinking an apparently incorrect one.
320
   */
321
0
  ret = _control_exists(control, major, minor);
322
0
  if (ret == -1)
323
0
    return_0; /* Failed to unlink existing incorrect node */
324
0
  if (ret)
325
0
    return 1; /* Already exists and correct */
326
327
0
  (void) dm_prepare_selinux_context(dm_dir(), S_IFDIR);
328
0
  old_umask = umask(DM_DEV_DIR_UMASK);
329
0
  ret = dm_create_dir(dm_dir());
330
0
  umask(old_umask);
331
0
  (void) dm_prepare_selinux_context(NULL, 0);
332
333
0
  if (!ret)
334
0
    return_0;
335
336
0
  log_verbose("Creating device %s (%u, %u)", control, major, minor);
337
338
0
  (void) dm_prepare_selinux_context(control, S_IFCHR);
339
0
  old_umask = umask(DM_CONTROL_NODE_UMASK);
340
0
  if (mknod(control, S_IFCHR | S_IRUSR | S_IWUSR,
341
0
      MKDEV(major, minor)) < 0)  {
342
0
    if (errno != EEXIST) {
343
0
      log_sys_error("mknod", control);
344
0
      ret = 0;
345
0
    } else if (_control_exists(control, major, minor) != 1) {
346
0
      stack; /* Invalid control node created by parallel command ? */
347
0
      ret = 0;
348
0
    }
349
0
  }
350
0
  umask(old_umask);
351
0
  (void) dm_prepare_selinux_context(NULL, 0);
352
353
0
  return ret;
354
0
}
355
#endif
356
357
/*
358
 * FIXME Update bitset in long-running process if dm claims new major numbers.
359
 */
360
/*
361
 * If require_module_loaded=0, caller is responsible to check
362
 * whether _dm_device_major or _dm_bitset is really set. If
363
 * it's not, it means the module is not loaded.
364
 */
365
static int _create_dm_bitset(int require_module_loaded)
366
0
{
367
0
  int r;
368
369
0
#ifdef DM_IOCTLS
370
0
  if (_dm_bitset || _dm_device_major)
371
0
    return 1;
372
373
0
  if (!_uname())
374
0
    return_0;
375
376
  /*
377
   * 2.6 kernels are limited to one major number.
378
   * Assume 2.4 kernels are patched not to.
379
   * FIXME Check _dm_version and _dm_version_minor if 2.6 changes this.
380
   */
381
0
  if (KERNEL_VERSION(_kernel_major, _kernel_minor, _kernel_release) >=
382
0
      KERNEL_VERSION(2, 6, 0))
383
0
    _dm_multiple_major_support = 0;
384
385
0
  if (!_dm_multiple_major_support) {
386
0
    if (!_get_proc_number(PROC_DEVICES, DM_NAME, &_dm_device_major,
387
0
              require_module_loaded))
388
0
      return 0;
389
0
    return 1;
390
0
  }
391
392
  /* Multiple major numbers supported */
393
0
  if (!(_dm_bitset = dm_bitset_create(NULL, NUMBER_OF_MAJORS)))
394
0
    return 0;
395
396
0
  r = _get_proc_number(PROC_DEVICES, DM_NAME, NULL, require_module_loaded);
397
0
  if (!r || r == 2) {
398
0
    dm_bitset_destroy(_dm_bitset);
399
0
    _dm_bitset = NULL;
400
    /*
401
     * It's not an error if we didn't find anything and we
402
     * didn't require module to be loaded at the same time.
403
     */
404
0
    return r == 2;
405
0
  }
406
407
0
  return 1;
408
#else
409
  return 0;
410
#endif
411
0
}
412
413
int dm_is_dm_major(uint32_t major)
414
0
{
415
0
  int r = 0;
416
417
0
  pthread_mutex_lock(&_control_fd_mutex);
418
0
  if (!_create_dm_bitset(0)) {
419
0
    pthread_mutex_unlock(&_control_fd_mutex);
420
0
    return 0;
421
0
  }
422
423
0
  if (_dm_multiple_major_support) {
424
0
    if (_dm_bitset)
425
0
      r = dm_bit(_dm_bitset, major) ? 1 : 0;
426
0
    pthread_mutex_unlock(&_control_fd_mutex);
427
0
    return r;
428
0
  }
429
430
0
  if (!_dm_device_major) {
431
0
    pthread_mutex_unlock(&_control_fd_mutex);
432
0
    return 0;
433
0
  }
434
435
0
  r = (major == _dm_device_major) ? 1 : 0;
436
0
  pthread_mutex_unlock(&_control_fd_mutex);
437
438
0
  return r;
439
0
}
440
441
static void _close_control_fd(void)
442
5.42k
{
443
5.42k
  if (_control_fd != -1) {
444
0
    if (close(_control_fd) < 0)
445
0
      log_sys_debug("close", "_control_fd");
446
0
    _control_fd = -1;
447
0
  }
448
5.42k
}
449
450
#ifdef DM_IOCTLS
451
static int _open_and_assign_control_fd(const char *control)
452
0
{
453
0
  if ((_control_fd = open(control, O_RDWR)) < 0) {
454
0
    log_sys_error("open", control);
455
0
    return 0;
456
0
  }
457
458
0
  return 1;
459
0
}
460
#endif
461
462
static int _open_control(void)
463
0
{
464
0
#ifdef DM_IOCTLS
465
0
  char control[PATH_MAX];
466
0
  uint32_t major = MISC_MAJOR;
467
0
  uint32_t minor = MAPPER_CTRL_MINOR;
468
469
0
  if (_control_fd != -1)
470
0
    return 1;
471
472
0
  if (!_uname())
473
0
    return_0;
474
475
0
  if (dm_snprintf(control, sizeof(control), "%s/%s", dm_dir(), DM_CONTROL_NODE) < 0)
476
0
    goto_bad;
477
478
  /*
479
   * Prior to 2.6.36 the minor number should be looked up in /proc.
480
   */
481
0
  if ((KERNEL_VERSION(_kernel_major, _kernel_minor, _kernel_release) <
482
0
       KERNEL_VERSION(2, 6, 36)) &&
483
0
      !_control_device_number(&major, &minor))
484
0
    goto_bad;
485
486
  /*
487
   * Create the node with correct major and minor if not already done.
488
   * Udev may already have created /dev/mapper/control
489
   * from the modules.devname file generated by depmod.
490
   */
491
0
  if (!_create_control(control, major, minor))
492
0
    goto_bad;
493
494
  /*
495
   * As of 2.6.36 kernels, the open can trigger autoloading dm-mod.
496
   */
497
0
  if (!_open_and_assign_control_fd(control))
498
0
    goto_bad;
499
500
0
  if (!_create_dm_bitset(1)) {
501
0
    log_error("Failed to set up list of device-mapper major numbers");
502
0
    return 0;
503
0
  }
504
505
0
  return 1;
506
507
0
bad:
508
0
  log_error("Failure to communicate with kernel device-mapper driver.");
509
0
  if (!geteuid())
510
0
    log_error("Check that device-mapper is available in the kernel.");
511
0
  return 0;
512
#else
513
  return 1;
514
#endif
515
0
}
516
517
static int _get_control_fd(void)
518
0
{
519
0
  int fd;
520
521
0
  pthread_mutex_lock(&_control_fd_mutex);
522
0
  if (_control_fd == -1)
523
0
    _open_control();
524
0
  fd = _control_fd;
525
0
  pthread_mutex_unlock(&_control_fd_mutex);
526
527
0
  return fd;
528
0
}
529
530
static void _dm_zfree_string(char *string)
531
0
{
532
0
  if (string) {
533
0
    memset(string, 0, strlen(string));
534
0
    __asm__ volatile ("" ::: "memory"); /* Compiler barrier. */
535
0
    dm_free(string);
536
0
  }
537
0
}
538
539
static void _dm_zfree_dmi(struct dm_ioctl *dmi)
540
0
{
541
0
  if (dmi) {
542
0
    memset(dmi, 0, dmi->data_size);
543
0
    __asm__ volatile ("" ::: "memory"); /* Compiler barrier. */
544
0
    dm_free(dmi);
545
0
  }
546
0
}
547
548
static void _dm_task_free_targets(struct dm_task *dmt)
549
0
{
550
0
  struct target *t, *n;
551
552
0
  for (t = dmt->head; t; t = n) {
553
0
    n = t->next;
554
0
    if (dmt->secure_data)
555
0
      _dm_zfree_string(t->params);
556
0
    else
557
0
      dm_free(t->params);
558
0
    dm_free(t->type);
559
0
    dm_free(t);
560
0
  }
561
562
0
  dmt->head = dmt->tail = NULL;
563
0
}
564
565
void dm_task_destroy(struct dm_task *dmt)
566
0
{
567
0
  _dm_task_free_targets(dmt);
568
0
  if (dmt->secure_data)
569
0
    _dm_zfree_dmi(dmt->dmi.v4);
570
0
  else
571
0
    dm_free(dmt->dmi.v4);
572
0
  dm_free(dmt->dev_name);
573
0
  dm_free(dmt->mangled_dev_name);
574
0
  dm_free(dmt->newname);
575
0
  dm_free(dmt->message);
576
0
  dm_free(dmt->geometry);
577
0
  dm_free(dmt->uuid);
578
0
  dm_free(dmt->mangled_uuid);
579
0
  dm_timestamp_destroy(dmt->ioctl_timestamp);
580
0
  dm_free(dmt);
581
0
}
582
583
/*
584
 * Protocol Version 4 functions.
585
 */
586
587
int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size)
588
0
{
589
0
  unsigned *v;
590
591
0
  if (!dmt->dmi.v4) {
592
0
    if (version)
593
0
      version[0] = '\0';
594
0
    return 0;
595
0
  }
596
597
0
  v = dmt->dmi.v4->version;
598
0
  if (version &&
599
0
      (snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]) < 0)) {
600
0
    log_error("Buffer for version is too short.");
601
0
    if (size > 0)
602
0
      version[0] = '\0';
603
0
    return 0;
604
0
  }
605
606
0
  return 1;
607
0
}
608
609
static int _check_version(char *version, size_t size)
610
0
{
611
0
  struct dm_task *task;
612
0
  int r;
613
614
0
  if (!(task = dm_task_create(DM_DEVICE_VERSION))) {
615
0
    log_error("Failed to get device-mapper version");
616
0
    version[0] = '\0';
617
0
    return 0;
618
0
  }
619
620
0
  r = dm_task_run(task);
621
0
  if (!dm_task_get_driver_version(task, version, size))
622
0
    stack;
623
624
0
  if (r && task->dmi.v4) {
625
0
    unsigned *v = task->dmi.v4->version;
626
0
    _dm_version = v[0];
627
0
    _dm_version_minor = v[1];
628
0
    _dm_version_patchlevel = v[2];
629
0
  }
630
631
0
  dm_task_destroy(task);
632
633
0
  return r;
634
0
}
635
636
static void _init_version(void)
637
0
{
638
0
  char libversion[64] = "", dmversion[64] = "";
639
640
0
  if (_check_version(dmversion, sizeof(dmversion)))
641
0
    return;
642
643
0
  dm_get_library_version(libversion, sizeof(libversion));
644
645
0
  log_error("Failed to communicate with device-mapper kernel driver (libdevmapper %s).",
646
0
      *libversion ? libversion : "(unknown version)");
647
648
0
  _version_ok = 0;
649
0
}
650
651
/*
652
 * Find out device-mapper's major version number the first time
653
 * this is called and whether or not we support it.
654
 */
655
int dm_check_version(void)
656
0
{
657
0
  pthread_once(&_version_once, _init_version);
658
659
0
  return _version_ok;
660
0
}
661
662
int dm_cookie_supported(void)
663
0
{
664
0
  return (dm_check_version() &&
665
0
    ((_dm_version == 4 && _dm_version_minor >= 15) || _dm_version > 4));
666
0
}
667
668
static int _dm_inactive_supported(void)
669
0
{
670
0
  int inactive_supported = 0;
671
672
0
  if (dm_check_version()) {
673
0
    if ((_dm_version == 4 && _dm_version_minor >= 16) || _dm_version > 4)
674
0
      inactive_supported = 1; /* upstream */
675
0
    else if (_dm_version == 4 && _dm_version_minor == 11 &&
676
0
       _dm_version_patchlevel >= 6 && _dm_version_patchlevel <= 40)
677
0
      inactive_supported = 1; /* RHEL 5.7 */
678
0
  }
679
680
0
  return inactive_supported;
681
0
}
682
683
int dm_message_supports_precise_timestamps(void)
684
0
{
685
  /*
686
   * 4.32.0 supports "precise_timestamps" and "histogram:" options
687
   * to @stats_create messages but lacks the ability to report
688
   * these properties via a subsequent @stats_list: require at
689
   * least 4.33.0 in order to use these features.
690
   */
691
0
  if (dm_check_version() &&
692
0
      ((_dm_version == 4 && _dm_version_minor >= 33) || _dm_version > 4))
693
0
    return 1;
694
0
  return 0;
695
0
}
696
697
void *dm_get_next_target(struct dm_task *dmt, void *next,
698
       uint64_t *start, uint64_t *length,
699
       char **target_type, char **params)
700
0
{
701
0
  struct target *t = (struct target *) next;
702
703
0
  if (!t)
704
0
    t = dmt->head;
705
706
0
  if (!t) {
707
0
    *start = 0;
708
0
    *length = 0;
709
0
    *target_type = 0;
710
0
    *params = 0;
711
0
    return NULL;
712
0
  }
713
714
0
  *start = t->start;
715
0
  *length = t->length;
716
0
  *target_type = t->type;
717
0
  *params = t->params;
718
719
0
  return t->next;
720
0
}
721
722
/* Unmarshal the target info returned from a status call */
723
static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi)
724
0
{
725
0
  char *outbuf = (char *) dmi + dmi->data_start;
726
0
  char *outptr = outbuf;
727
0
  uint32_t i;
728
0
  struct dm_target_spec *spec;
729
730
0
  _dm_task_free_targets(dmt);
731
732
0
  for (i = 0; i < dmi->target_count; i++) {
733
0
    spec = (struct dm_target_spec *) outptr;
734
0
    if (!dm_task_add_target(dmt, spec->sector_start,
735
0
          spec->length,
736
0
          spec->target_type,
737
0
          outptr + sizeof(*spec))) {
738
0
      return 0;
739
0
    }
740
741
0
    outptr = outbuf + spec->next;
742
0
  }
743
744
0
  return 1;
745
0
}
746
747
int dm_format_dev(char *buf, int bufsize, uint32_t dev_major,
748
      uint32_t dev_minor)
749
0
{
750
0
  int r;
751
752
0
  if (bufsize < 8)
753
0
    return 0;
754
755
0
  r = snprintf(buf, (size_t) bufsize, "%u:%u", dev_major, dev_minor);
756
0
  if (r < 0 || r > bufsize - 1)
757
0
    return 0;
758
759
0
  return 1;
760
0
}
761
762
DM_EXPORT_NEW_SYMBOL(int, dm_task_get_info, 1_02_97)
763
  (struct dm_task *dmt, struct dm_info *info)
764
0
{
765
0
  if (!dmt->dmi.v4)
766
0
    return 0;
767
768
0
  memset(info, 0, sizeof(*info));
769
770
0
  info->exists = dmt->dmi.v4->flags & DM_EXISTS_FLAG ? 1 : 0;
771
0
  if (!info->exists)
772
0
    return 1;
773
774
0
  info->suspended = dmt->dmi.v4->flags & DM_SUSPEND_FLAG ? 1 : 0;
775
0
  info->read_only = dmt->dmi.v4->flags & DM_READONLY_FLAG ? 1 : 0;
776
0
  info->live_table = dmt->dmi.v4->flags & DM_ACTIVE_PRESENT_FLAG ? 1 : 0;
777
0
  info->inactive_table = dmt->dmi.v4->flags & DM_INACTIVE_PRESENT_FLAG ?
778
0
      1 : 0;
779
0
  info->deferred_remove = dmt->dmi.v4->flags & DM_DEFERRED_REMOVE_FLAG ? 1 : 0;
780
0
  info->internal_suspend = (dmt->dmi.v4->flags & DM_INTERNAL_SUSPEND_FLAG) ? 1 : 0;
781
0
  info->target_count = dmt->dmi.v4->target_count;
782
0
  info->open_count = dmt->dmi.v4->open_count;
783
0
  info->event_nr = dmt->dmi.v4->event_nr;
784
0
  info->major = MAJOR(dmt->dmi.v4->dev);
785
0
  info->minor = MINOR(dmt->dmi.v4->dev);
786
787
0
  return 1;
788
0
}
789
790
uint32_t dm_task_get_read_ahead(const struct dm_task *dmt, uint32_t *read_ahead)
791
0
{
792
0
  const char *dev_name;
793
794
0
  *read_ahead = 0;
795
796
0
  if (!dmt->dmi.v4 || !(dmt->dmi.v4->flags & DM_EXISTS_FLAG))
797
0
    return 0;
798
799
0
  if (*dmt->dmi.v4->name)
800
0
    dev_name = dmt->dmi.v4->name;
801
0
  else if (!(dev_name = DEV_NAME(dmt))) {
802
0
    log_error("Get read ahead request failed: device name unrecorded.");
803
0
    return 0;
804
0
  }
805
806
0
  return get_dev_node_read_ahead(dev_name, MAJOR(dmt->dmi.v4->dev),
807
0
               MINOR(dmt->dmi.v4->dev), read_ahead);
808
0
}
809
810
struct dm_deps *dm_task_get_deps(struct dm_task *dmt)
811
0
{
812
0
  if (!dmt) {
813
0
    log_error(INTERNAL_ERROR "Missing dm_task.");
814
0
    return NULL;
815
0
  }
816
817
0
  return (struct dm_deps *) (((char *) dmt->dmi.v4) +
818
0
           dmt->dmi.v4->data_start);
819
0
}
820
821
/*
822
 * Round up the ptr to an 8-byte boundary.
823
 * Follow kernel pattern.
824
 */
825
0
#define ALIGN_MASK 7
826
static size_t _align_val(size_t val)
827
0
{
828
0
  return (val + ALIGN_MASK) & ~ALIGN_MASK;
829
0
}
830
static void *_align_ptr(void *ptr)
831
0
{
832
0
  return (void *)(uintptr_t)_align_val((size_t)ptr);
833
0
}
834
835
static int _has_event_nr = 0;
836
static pthread_once_t _has_event_nr_once = PTHREAD_ONCE_INIT;
837
838
static void _init_has_event_nr(void)
839
0
{
840
0
  _has_event_nr = dm_check_version() &&
841
0
    ((_dm_version == 4 && _dm_version_minor >= 38) || _dm_version > 4);
842
0
}
843
844
0
static int _check_has_event_nr(void) {
845
0
  pthread_once(&_has_event_nr_once, _init_has_event_nr);
846
847
0
  return _has_event_nr;
848
0
}
849
850
struct dm_names *dm_task_get_names(struct dm_task *dmt)
851
0
{
852
0
  return (struct dm_names *) (((char *) dmt->dmi.v4) +
853
0
            dmt->dmi.v4->data_start);
854
0
}
855
856
struct dm_versions *dm_task_get_versions(struct dm_task *dmt)
857
0
{
858
0
  return (struct dm_versions *) (((char *) dmt->dmi.v4) +
859
0
               dmt->dmi.v4->data_start);
860
0
}
861
862
int dm_task_get_device_list(struct dm_task *dmt, struct dm_list **devs_list,
863
          unsigned *devs_features)
864
0
{
865
0
  struct dm_names *names, *names1 = NULL;
866
0
  struct dm_active_device *dm_dev, *dm_new_dev;
867
0
  struct dm_list *devs;
868
0
  unsigned next = 0;
869
0
  uint32_t *event_nr;
870
0
  char *uuid_ptr;
871
0
  size_t len;
872
0
  int cnt = 0;
873
874
0
  *devs_list = 0;
875
0
  *devs_features = 0;
876
877
0
  if ((names = dm_task_get_names(dmt)) && names->dev) {
878
0
    names1 = names;
879
0
    if (!names->name[0])
880
0
      cnt = -1; /* -> cnt == 0 when no device is really present */
881
0
    do {
882
0
      names1 = (struct dm_names *)((char *) names1 + next);
883
0
      next = names1->next;
884
0
      ++cnt;
885
0
    } while (next);
886
0
  }
887
888
  /* buffer for devs +  sorted ptrs + dm_devs + aligned strings */
889
0
  if (!(devs = malloc(sizeof(*devs) + cnt * (2 * sizeof(void*) + sizeof(*dm_dev)) +
890
0
          (cnt ? (char*)names1 - (char*)names + 256 : 0))))
891
0
    return_0;
892
893
0
  dm_list_init(devs);
894
895
0
  if (!cnt) {
896
    /* nothing in the list -> mark all features present */
897
0
    *devs_features |= (DM_DEVICE_LIST_HAS_EVENT_NR | DM_DEVICE_LIST_HAS_UUID);
898
0
    goto out; /* nothing else to do */
899
0
  }
900
901
  /* Shift position where to store individual dm_devs */
902
0
  dm_dev = (struct dm_active_device *) ((long*) (devs + 1) + cnt);
903
904
0
  do {
905
0
    names = (struct dm_names *)((char *) names + next);
906
907
0
    dm_dev->devno = (dev_t) names->dev;
908
0
    dm_dev->name = (const char *)(dm_dev + 1);
909
0
    dm_dev->event_nr = 0;
910
0
    dm_dev->uuid = "";
911
912
0
    len = strlen(names->name) + 1;
913
0
    memcpy((char*)dm_dev->name, names->name, len);
914
915
0
    dm_new_dev = _align_ptr((char*)(dm_dev + 1) + len);
916
0
    if (_check_has_event_nr()) {
917
918
0
      *devs_features |= DM_DEVICE_LIST_HAS_EVENT_NR;
919
0
      event_nr = _align_ptr(names->name + len);
920
0
      dm_dev->event_nr = event_nr[0];
921
922
0
      if ((event_nr[1] & DM_NAME_LIST_FLAG_HAS_UUID)) {
923
0
        *devs_features |= DM_DEVICE_LIST_HAS_UUID;
924
0
        uuid_ptr = _align_ptr(event_nr + 2);
925
0
        len = strlen(uuid_ptr) + 1;
926
0
        memcpy(dm_new_dev, uuid_ptr, len);
927
0
        dm_dev->uuid = (const char *) dm_new_dev;
928
0
        dm_new_dev = _align_ptr((char*)dm_new_dev + len);
929
0
      }
930
0
    }
931
932
0
    dm_list_add(devs, &dm_dev->list);
933
0
    dm_dev = dm_new_dev;
934
0
    next = names->next;
935
0
  } while (next);
936
937
0
    out:
938
0
  *devs_list = devs;
939
940
0
  return 1;
941
0
}
942
943
void dm_device_list_destroy(struct dm_list **devs_list)
944
0
{
945
0
  struct dm_device_list *devs = (struct dm_device_list *) *devs_list;
946
947
0
  if (devs) {
948
0
    free(devs);
949
0
    *devs_list = NULL;
950
0
  }
951
0
}
952
953
int dm_device_list_equal(const struct dm_list *list1, const struct dm_list *list2)
954
0
{
955
0
  const struct dm_active_device *dev1, *dev2;
956
0
  const struct dm_list *l2;
957
958
0
  if (!list1 || !list2)
959
0
    return (list1 == list2);
960
961
0
  if (!(l2 = dm_list_first(list2)))
962
0
    return dm_list_empty(list1);
963
964
0
  dm_list_iterate_items(dev1, list1) {
965
0
    dev2 = dm_list_item(l2, struct dm_active_device);
966
0
    if ((dev1->devno != dev2->devno) || strcmp(dev1->uuid, dev2->uuid))
967
0
      return 0;
968
0
    if (!(l2 = dm_list_next(list2, l2)))
969
0
      return !dm_list_next(list1, &dev1->list);
970
0
  }
971
972
0
  return 1;
973
0
}
974
975
const char *dm_task_get_message_response(struct dm_task *dmt)
976
0
{
977
0
  const char *start, *end;
978
979
0
  if (!(dmt->dmi.v4->flags & DM_DATA_OUT_FLAG))
980
0
    return NULL;
981
982
0
  start = (const char *) dmt->dmi.v4 + dmt->dmi.v4->data_start;
983
0
  end = (const char *) dmt->dmi.v4 + dmt->dmi.v4->data_size;
984
985
0
  if (end < start) {
986
0
    log_error(INTERNAL_ERROR "Corrupted message structure returned: start %d > end %d", (int)dmt->dmi.v4->data_start, (int)dmt->dmi.v4->data_size);
987
0
    return NULL;
988
0
  }
989
990
0
  if (!memchr(start, 0, end - start)) {
991
0
    log_error(INTERNAL_ERROR "Message response doesn't contain terminating NUL character");
992
0
    return NULL;
993
0
  }
994
995
0
  return start;
996
0
}
997
998
int dm_task_set_ro(struct dm_task *dmt)
999
0
{
1000
0
  dmt->read_only = 1;
1001
0
  return 1;
1002
0
}
1003
1004
int dm_task_set_read_ahead(struct dm_task *dmt, uint32_t read_ahead,
1005
         uint32_t read_ahead_flags)
1006
0
{
1007
0
  dmt->read_ahead = read_ahead;
1008
0
  dmt->read_ahead_flags = read_ahead_flags;
1009
1010
0
  return 1;
1011
0
}
1012
1013
int dm_task_suppress_identical_reload(struct dm_task *dmt)
1014
0
{
1015
0
  dmt->suppress_identical_reload = 1;
1016
0
  return 1;
1017
0
}
1018
1019
int dm_task_set_add_node(struct dm_task *dmt, dm_add_node_t add_node)
1020
0
{
1021
0
  switch (add_node) {
1022
0
  case DM_ADD_NODE_ON_RESUME:
1023
0
  case DM_ADD_NODE_ON_CREATE:
1024
0
    dmt->add_node = add_node;
1025
0
    return 1;
1026
0
  default:
1027
0
    log_error("Unknown add node parameter");
1028
0
    return 0;
1029
0
  }
1030
0
}
1031
1032
int dm_task_set_newuuid(struct dm_task *dmt, const char *newuuid)
1033
0
{
1034
0
  dm_string_mangling_t mangling_mode = dm_get_name_mangling_mode();
1035
0
  char mangled_uuid[DM_UUID_LEN];
1036
0
  int r = 0;
1037
1038
0
  if (strlen(newuuid) >= DM_UUID_LEN) {
1039
0
    log_error("Uuid \"%s\" too long", newuuid);
1040
0
    return 0;
1041
0
  }
1042
1043
0
  if (!check_multiple_mangled_string_allowed(newuuid, "new UUID", mangling_mode))
1044
0
    return_0;
1045
1046
0
  if (mangling_mode != DM_STRING_MANGLING_NONE &&
1047
0
      (r = mangle_string(newuuid, "new UUID", strlen(newuuid), mangled_uuid,
1048
0
             sizeof(mangled_uuid), mangling_mode)) < 0) {
1049
0
    log_error("Failed to mangle new device UUID \"%s\"", newuuid);
1050
0
    return 0;
1051
0
  }
1052
1053
0
  if (r) {
1054
0
    log_debug_activation("New device uuid mangled [%s]: %s --> %s",
1055
0
             mangling_mode == DM_STRING_MANGLING_AUTO ? "auto" : "hex",
1056
0
             newuuid, mangled_uuid);
1057
0
    newuuid = mangled_uuid;
1058
0
  }
1059
1060
0
  dm_free(dmt->newname);
1061
0
  if (!(dmt->newname = dm_strdup(newuuid))) {
1062
0
    log_error("dm_task_set_newuuid: strdup(%s) failed", newuuid);
1063
0
    return 0;
1064
0
  }
1065
0
  dmt->new_uuid = 1;
1066
1067
0
  return 1;
1068
0
}
1069
1070
int dm_task_set_message(struct dm_task *dmt, const char *message)
1071
0
{
1072
0
  dm_free(dmt->message);
1073
0
  if (!(dmt->message = dm_strdup(message))) {
1074
0
    log_error("dm_task_set_message: strdup failed");
1075
0
    return 0;
1076
0
  }
1077
1078
0
  return 1;
1079
0
}
1080
1081
int dm_task_set_sector(struct dm_task *dmt, uint64_t sector)
1082
0
{
1083
0
  dmt->sector = sector;
1084
1085
0
  return 1;
1086
0
}
1087
1088
int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads,
1089
       const char *sectors, const char *start)
1090
0
{
1091
0
  dm_free(dmt->geometry);
1092
0
  if (dm_asprintf(&(dmt->geometry), "%s %s %s %s",
1093
0
      cylinders, heads, sectors, start) < 0) {
1094
0
    log_error("dm_task_set_geometry: sprintf failed");
1095
0
    return 0;
1096
0
  }
1097
1098
0
  return 1;
1099
0
}
1100
1101
int dm_task_no_flush(struct dm_task *dmt)
1102
0
{
1103
0
  dmt->no_flush = 1;
1104
1105
0
  return 1;
1106
0
}
1107
1108
int dm_task_no_open_count(struct dm_task *dmt)
1109
0
{
1110
0
  dmt->no_open_count = 1;
1111
1112
0
  return 1;
1113
0
}
1114
1115
int dm_task_skip_lockfs(struct dm_task *dmt)
1116
0
{
1117
0
  dmt->skip_lockfs = 1;
1118
1119
0
  return 1;
1120
0
}
1121
1122
int dm_task_secure_data(struct dm_task *dmt)
1123
0
{
1124
0
  dmt->secure_data = 1;
1125
1126
0
  return 1;
1127
0
}
1128
1129
int dm_task_ima_measurement(struct dm_task *dmt)
1130
0
{
1131
0
  dmt->ima_measurement = 1;
1132
1133
0
  return 1;
1134
0
}
1135
1136
int dm_task_retry_remove(struct dm_task *dmt)
1137
0
{
1138
0
  dmt->retry_remove = 1;
1139
1140
0
  return 1;
1141
0
}
1142
1143
int dm_task_deferred_remove(struct dm_task *dmt)
1144
0
{
1145
0
  dmt->deferred_remove = 1;
1146
1147
0
  return 1;
1148
0
}
1149
1150
int dm_task_query_inactive_table(struct dm_task *dmt)
1151
0
{
1152
0
  dmt->query_inactive_table = 1;
1153
1154
0
  return 1;
1155
0
}
1156
1157
int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr)
1158
0
{
1159
0
  dmt->event_nr = event_nr;
1160
1161
0
  return 1;
1162
0
}
1163
1164
int dm_task_set_record_timestamp(struct dm_task *dmt)
1165
0
{
1166
0
  if (!dmt->ioctl_timestamp)
1167
0
    dmt->ioctl_timestamp = dm_timestamp_alloc();
1168
1169
0
  if (!dmt->ioctl_timestamp)
1170
0
    return_0;
1171
1172
0
  dmt->record_timestamp = 1;
1173
1174
0
  return 1;
1175
0
}
1176
1177
struct dm_timestamp *dm_task_get_ioctl_timestamp(struct dm_task *dmt)
1178
0
{
1179
0
  return dmt->record_timestamp ? dmt->ioctl_timestamp : NULL;
1180
0
}
1181
1182
struct target *create_target(uint64_t start, uint64_t len, const char *type,
1183
           const char *params)
1184
0
{
1185
0
  struct target *t;
1186
1187
0
  if (strlen(type) >= DM_MAX_TYPE_NAME) {
1188
0
    log_error("Target type name %s is too long.", type);
1189
0
    return NULL;
1190
0
  }
1191
1192
0
  if (!(t = dm_zalloc(sizeof(*t)))) {
1193
0
    log_error("create_target: malloc(%" PRIsize_t ") failed",
1194
0
        sizeof(*t));
1195
0
    return NULL;
1196
0
  }
1197
1198
0
  if (!(t->params = dm_strdup(params))) {
1199
0
    log_error("create_target: strdup(params) failed");
1200
0
    goto bad;
1201
0
  }
1202
1203
0
  if (!(t->type = dm_strdup(type))) {
1204
0
    log_error("create_target: strdup(type) failed");
1205
0
    goto bad;
1206
0
  }
1207
1208
0
  t->start = start;
1209
0
  t->length = len;
1210
0
  return t;
1211
1212
0
      bad:
1213
0
  _dm_zfree_string(t->params);
1214
0
  dm_free(t->type);
1215
0
  dm_free(t);
1216
0
  return NULL;
1217
0
}
1218
1219
static char *_add_target(struct target *t, char *out, char *end)
1220
0
{
1221
0
  char *out_sp = out;
1222
0
  struct dm_target_spec sp;
1223
0
  size_t sp_size = sizeof(struct dm_target_spec);
1224
0
  unsigned int backslash_count = 0;
1225
0
  int len;
1226
0
  char *pt;
1227
1228
0
  if (strlen(t->type) >= sizeof(sp.target_type)) {
1229
0
    log_error("Target type name %s is too long.", t->type);
1230
0
    return NULL;
1231
0
  }
1232
1233
0
  sp.status = 0;
1234
0
  sp.sector_start = t->start;
1235
0
  sp.length = t->length;
1236
0
  strncpy(sp.target_type, t->type, sizeof(sp.target_type) - 1);
1237
0
  sp.target_type[sizeof(sp.target_type) - 1] = '\0';
1238
1239
0
  out += sp_size;
1240
0
  pt = t->params;
1241
1242
0
  while (*pt)
1243
0
    if (*pt++ == '\\')
1244
0
      backslash_count++;
1245
1246
0
  len = strlen(t->params) + 1;
1247
1248
0
  if ((out >= end) || (out + len + backslash_count) >= end) {
1249
0
    log_error("Ran out of memory building ioctl parameter");
1250
0
    return NULL;
1251
0
  }
1252
1253
0
  if (backslash_count) {
1254
    /* replace "\" with "\\" */
1255
0
    pt = t->params;
1256
0
    do {
1257
0
      if (*pt == '\\')
1258
0
        *out++ = '\\';
1259
0
      *out++ = *pt++;
1260
0
    } while (*pt);
1261
0
    *out++ = '\0';
1262
0
  }
1263
0
  else {
1264
0
    memcpy(out, t->params, len);
1265
0
    out += len;
1266
0
  }
1267
1268
  /* align next block */
1269
0
  out = _align(out, ALIGNMENT);
1270
1271
0
  sp.next = out - out_sp;
1272
0
  memcpy(out_sp, &sp, sp_size);
1273
1274
0
  return out;
1275
0
}
1276
1277
static int _lookup_dev_name(uint64_t dev, char *buf, size_t len)
1278
0
{
1279
0
  struct dm_names *names;
1280
0
  unsigned next = 0;
1281
0
  struct dm_task *dmt;
1282
0
  int r = 0;
1283
1284
0
  if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
1285
0
    return 0;
1286
1287
0
  if (!dm_task_run(dmt))
1288
0
    goto out;
1289
1290
0
  if (!(names = dm_task_get_names(dmt)))
1291
0
    goto out;
1292
1293
0
  if (!names->dev)
1294
0
    goto out;
1295
1296
0
  do {
1297
0
    names = (struct dm_names *)((char *) names + next);
1298
0
    if (names->dev == dev) {
1299
0
      memccpy(buf, names->name, 0, len);
1300
0
      r = 1;
1301
0
      break;
1302
0
    }
1303
0
    next = names->next;
1304
0
  } while (next);
1305
1306
0
      out:
1307
0
  dm_task_destroy(dmt);
1308
0
  return r;
1309
0
}
1310
1311
static int _add_params(int type)
1312
0
{
1313
0
  switch (type) {
1314
0
  case DM_DEVICE_REMOVE_ALL:
1315
0
  case DM_DEVICE_CREATE:
1316
0
  case DM_DEVICE_REMOVE:
1317
0
  case DM_DEVICE_SUSPEND:
1318
0
  case DM_DEVICE_STATUS:
1319
0
  case DM_DEVICE_CLEAR:
1320
0
  case DM_DEVICE_ARM_POLL:
1321
0
    return 0; /* IOCTL_FLAGS_NO_PARAMS in drivers/md/dm-ioctl.c */
1322
0
  default:
1323
0
    return 1;
1324
0
  }
1325
0
}
1326
1327
static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
1328
0
{
1329
0
  size_t min_size;
1330
0
  const int (*version)[3];
1331
1332
0
  struct dm_ioctl *dmi;
1333
0
  struct target *t;
1334
0
  struct dm_target_msg *tmsg;
1335
0
  size_t len = sizeof(struct dm_ioctl);
1336
0
  size_t message_len = 0, newname_len = 0, geometry_len = 0;
1337
0
  char *b, *e;
1338
0
  int count = 0;
1339
1340
0
  if (_add_params(dmt->type))
1341
0
    for (t = dmt->head; t; t = t->next) {
1342
0
      len += sizeof(struct dm_target_spec);
1343
0
      len += strlen(t->params) + 1 + ALIGNMENT;
1344
0
      count++;
1345
0
    }
1346
0
  else if (dmt->head)
1347
0
    log_debug_activation(INTERNAL_ERROR "dm '%s' ioctl should not define parameters.",
1348
0
             _cmd_data_v4[dmt->type].name);
1349
0
  switch (dmt->type) {
1350
0
  case DM_DEVICE_CREATE:
1351
0
  case DM_DEVICE_DEPS:
1352
0
  case DM_DEVICE_LIST:
1353
0
  case DM_DEVICE_STATUS:
1354
0
  case DM_DEVICE_TABLE:
1355
0
  case DM_DEVICE_TARGET_MSG:
1356
0
    min_size = 16 * 1024;
1357
0
    break;
1358
0
  default:
1359
0
    min_size = 2 * 1024;
1360
0
  }
1361
1362
0
  if (count && (dmt->sector || dmt->message)) {
1363
0
    log_error("targets and message are incompatible");
1364
0
    return NULL;
1365
0
  }
1366
1367
0
  if (count && dmt->newname) {
1368
0
    log_error("targets and rename are incompatible");
1369
0
    return NULL;
1370
0
  }
1371
1372
0
  if (count && dmt->geometry) {
1373
0
    log_error("targets and geometry are incompatible");
1374
0
    return NULL;
1375
0
  }
1376
1377
0
  if (dmt->newname && (dmt->sector || dmt->message)) {
1378
0
    log_error("message and rename are incompatible");
1379
0
    return NULL;
1380
0
  }
1381
1382
0
  if (dmt->newname && dmt->geometry) {
1383
0
    log_error("geometry and rename are incompatible");
1384
0
    return NULL;
1385
0
  }
1386
1387
0
  if (dmt->geometry && (dmt->sector || dmt->message)) {
1388
0
    log_error("geometry and message are incompatible");
1389
0
    return NULL;
1390
0
  }
1391
1392
0
  if (dmt->sector && !dmt->message) {
1393
0
    log_error("message is required with sector");
1394
0
    return NULL;
1395
0
  }
1396
1397
0
  if (dmt->newname) {
1398
0
    newname_len = strlen(dmt->newname) + 1;
1399
0
    len += newname_len;
1400
0
  }
1401
1402
0
  if (dmt->message) {
1403
0
    message_len = strlen(dmt->message) + 1;
1404
0
    len += sizeof(struct dm_target_msg) + message_len;
1405
0
  }
1406
1407
0
  if (dmt->geometry) {
1408
0
    geometry_len = strlen(dmt->geometry) + 1;
1409
0
    len += geometry_len;
1410
0
  }
1411
1412
  /*
1413
   * Give len a minimum size so that we have space to store
1414
   * dependencies or status information.
1415
   */
1416
0
  if (len < min_size)
1417
0
    len = min_size;
1418
1419
  /* Increase buffer size if repeating because buffer was too small */
1420
0
  while (repeat_count--)
1421
0
    len *= 2;
1422
1423
0
  if (!(dmi = dm_zalloc(len)))
1424
0
    return NULL;
1425
1426
0
  version = &_cmd_data_v4[dmt->type].version;
1427
1428
0
  dmi->version[0] = (*version)[0];
1429
0
  dmi->version[1] = (*version)[1];
1430
0
  dmi->version[2] = (*version)[2];
1431
1432
0
  dmi->data_size = len;
1433
0
  dmi->data_start = sizeof(struct dm_ioctl);
1434
1435
0
  if (dmt->minor >= 0) {
1436
0
    if (!_dm_multiple_major_support && dmt->allow_default_major_fallback &&
1437
0
        dmt->major != (int) _dm_device_major) {
1438
0
      log_verbose("Overriding major number of %d "
1439
0
            "with %u for persistent device.",
1440
0
            dmt->major, _dm_device_major);
1441
0
      dmt->major = _dm_device_major;
1442
0
    }
1443
1444
0
    if (dmt->major <= 0) {
1445
0
      log_error("Missing major number for persistent device.");
1446
0
      goto bad;
1447
0
    }
1448
1449
0
    dmi->flags |= DM_PERSISTENT_DEV_FLAG;
1450
0
    dmi->dev = MKDEV(dmt->major, dmt->minor);
1451
0
  }
1452
1453
  /* Does driver support device number referencing? */
1454
0
  if (_dm_version_minor < 3 && !DEV_NAME(dmt) && !DEV_UUID(dmt) && dmi->dev) {
1455
0
    if (!_lookup_dev_name(dmi->dev, dmi->name, sizeof(dmi->name))) {
1456
0
      log_error("Unable to find name for device (%d:%d).",
1457
0
          dmt->major, dmt->minor);
1458
0
      goto bad;
1459
0
    }
1460
0
    log_verbose("device (%d:%d) is %s "
1461
0
          "for compatibility with old kernel.",
1462
0
          dmt->major, dmt->minor, dmi->name);
1463
0
  }
1464
1465
  /* FIXME Until resume ioctl supplies name, use dev_name for readahead */
1466
0
  if (DEV_NAME(dmt) &&
1467
0
      (((dmt->type != DM_DEVICE_RESUME) &&
1468
0
        (dmt->type != DM_DEVICE_RELOAD) &&
1469
0
        (dmt->type != DM_DEVICE_REMOVE)) ||
1470
0
       (dmt->minor < 0) || (dmt->major < 0)))
1471
    /* When RESUME, RELOAD or REMOVE sets maj:min and dev_name,
1472
     * use just maj:min for the ioctl; dev_name stays on dmt
1473
     * for error/debug messages and _dm_task_node_ops */
1474
0
    memccpy(dmi->name, DEV_NAME(dmt), 0, sizeof(dmi->name));
1475
1476
0
  if (DEV_UUID(dmt))
1477
0
    memccpy(dmi->uuid, DEV_UUID(dmt), 0, sizeof(dmi->uuid));
1478
1479
0
  if (dmt->type == DM_DEVICE_SUSPEND)
1480
0
    dmi->flags |= DM_SUSPEND_FLAG;
1481
0
  if (dmt->no_flush) {
1482
0
    if (_dm_version_minor < 12)
1483
0
      log_verbose("No flush flag unsupported by kernel. "
1484
0
            "Buffers will be flushed.");
1485
0
    else
1486
0
      dmi->flags |= DM_NOFLUSH_FLAG;
1487
0
  }
1488
0
  if (dmt->read_only)
1489
0
    dmi->flags |= DM_READONLY_FLAG;
1490
0
  if (dmt->skip_lockfs)
1491
0
    dmi->flags |= DM_SKIP_LOCKFS_FLAG;
1492
0
  if (dmt->deferred_remove && (dmt->type == DM_DEVICE_REMOVE || dmt->type == DM_DEVICE_REMOVE_ALL))
1493
0
    dmi->flags |= DM_DEFERRED_REMOVE_FLAG;
1494
1495
0
  if (dmt->secure_data) {
1496
0
    if (_dm_version_minor < 20)
1497
0
      log_verbose("Secure data flag unsupported by kernel. "
1498
0
            "Buffers will not be wiped after use.");
1499
0
    dmi->flags |= DM_SECURE_DATA_FLAG;
1500
0
  }
1501
0
  if (dmt->query_inactive_table) {
1502
0
    if (!_dm_inactive_supported())
1503
0
      log_warn_suppress(_dm_warn_inactive_suppress++,
1504
0
            "WARNING: Inactive table query unsupported by kernel. "
1505
0
            "It will use live table.");
1506
0
    dmi->flags |= DM_QUERY_INACTIVE_TABLE_FLAG;
1507
0
  }
1508
0
  if (dmt->new_uuid) {
1509
0
    if (_dm_version_minor < 19) {
1510
0
      log_error("Setting UUID unsupported by kernel. "
1511
0
          "Aborting operation.");
1512
0
      goto bad;
1513
0
    }
1514
0
    dmi->flags |= DM_UUID_FLAG;
1515
0
  }
1516
0
  if (dmt->ima_measurement) {
1517
0
    if (_dm_version_minor < 45) {
1518
0
      log_error("IMA measurement unsupported by kernel. "
1519
0
          "Aborting operation.");
1520
0
      goto bad;
1521
0
    }
1522
0
    dmi->flags |= DM_IMA_MEASUREMENT_FLAG;
1523
0
  }
1524
1525
0
  dmi->target_count = count;
1526
0
  dmi->event_nr = dmt->event_nr;
1527
1528
0
  b = (char *) (dmi + 1);
1529
0
  e = (char *) dmi + len;
1530
1531
0
  if (_add_params(dmt->type))
1532
0
    for (t = dmt->head; t; t = t->next)
1533
0
      if (!(b = _add_target(t, b, e)))
1534
0
        goto_bad;
1535
1536
0
  if (dmt->newname)
1537
0
    memcpy(b, dmt->newname, newname_len);
1538
1539
0
  if (dmt->message) {
1540
0
    tmsg = (struct dm_target_msg *) b;
1541
0
    tmsg->sector = dmt->sector;
1542
0
    memcpy(tmsg->message, dmt->message, message_len);
1543
0
  }
1544
1545
0
  if (dmt->geometry)
1546
0
    memcpy(b, dmt->geometry, geometry_len);
1547
1548
0
  return dmi;
1549
1550
0
      bad:
1551
0
  _dm_zfree_dmi(dmi);
1552
0
  return NULL;
1553
0
}
1554
1555
static int _process_mapper_dir(struct dm_task *dmt)
1556
0
{
1557
0
  struct dirent *dirent;
1558
0
  DIR *d;
1559
0
  const char *dir;
1560
0
  int r = 1;
1561
1562
0
  dir = dm_dir();
1563
0
  if (!(d = opendir(dir))) {
1564
0
    log_sys_error("opendir", dir);
1565
0
    return 0;
1566
0
  }
1567
1568
0
  while ((dirent = readdir(d))) {
1569
0
    if (!strcmp(dirent->d_name, ".") ||
1570
0
        !strcmp(dirent->d_name, "..") ||
1571
0
        !strcmp(dirent->d_name, "control"))
1572
0
      continue;
1573
0
    if (!dm_task_set_name(dmt, dirent->d_name)) {
1574
0
      r = 0;
1575
0
      stack;
1576
0
      continue; /* try next name */
1577
0
    }
1578
0
    if (!dm_task_run(dmt)) {
1579
0
      r = 0;
1580
0
      stack;  /* keep going */
1581
0
    }
1582
0
  }
1583
1584
0
  if (closedir(d))
1585
0
    log_sys_debug("closedir", dir);
1586
1587
0
  return r;
1588
0
}
1589
1590
static int _process_all_v4(struct dm_task *dmt)
1591
0
{
1592
0
  struct dm_task *task;
1593
0
  struct dm_names *names;
1594
0
  unsigned next = 0;
1595
0
  int r = 1;
1596
1597
0
  if (!(task = dm_task_create(DM_DEVICE_LIST)))
1598
0
    return 0;
1599
1600
0
  if (!dm_task_run(task)) {
1601
0
    r = 0;
1602
0
    goto out;
1603
0
  }
1604
1605
0
  if (!(names = dm_task_get_names(task))) {
1606
0
    r = 0;
1607
0
    goto out;
1608
0
  }
1609
1610
0
  if (!names->dev)
1611
0
    goto out;
1612
1613
0
  do {
1614
0
    names = (struct dm_names *)((char *) names + next);
1615
0
    if (!dm_task_set_name(dmt, names->name)) {
1616
0
      r = 0;
1617
0
      goto out;
1618
0
    }
1619
0
    if (!dm_task_run(dmt))
1620
0
      r = 0;
1621
0
    next = names->next;
1622
0
  } while (next);
1623
1624
0
      out:
1625
0
  dm_task_destroy(task);
1626
0
  return r;
1627
0
}
1628
1629
static int _mknodes_v4(struct dm_task *dmt)
1630
0
{
1631
0
  (void) _process_mapper_dir(dmt);
1632
1633
0
  return _process_all_v4(dmt);
1634
0
}
1635
1636
/*
1637
 * If an operation that uses a cookie fails, decrement the
1638
 * semaphore instead of udev.
1639
 */
1640
static int _udev_complete(struct dm_task *dmt)
1641
0
{
1642
0
  uint16_t base;
1643
1644
0
  if (dmt->cookie_set &&
1645
0
      (base = dmt->event_nr & ~DM_UDEV_FLAGS_MASK))
1646
    /* strip flags from the cookie and use cookie magic instead */
1647
0
    return dm_udev_complete(base | (DM_COOKIE_MAGIC <<
1648
0
            DM_UDEV_FLAGS_SHIFT));
1649
1650
0
  return 1;
1651
0
}
1652
1653
#ifdef DM_IOCTLS
1654
static int _check_uevent_generated(struct dm_ioctl *dmi)
1655
0
{
1656
0
  if (!dm_check_version() ||
1657
0
      ((_dm_version == 4 && _dm_version_minor < 17) || _dm_version < 4))
1658
    /* can't check, assume uevent is generated */
1659
0
    return 1;
1660
1661
0
  return dmi->flags & DM_UEVENT_GENERATED_FLAG;
1662
0
}
1663
#endif
1664
1665
/*
1666
 * Create a RELOAD task and populate it with table data.
1667
 * Used by both _create_and_load_v4() and the async create chain.
1668
 * The target list (head/tail) is moved -- caller must NULL its own copy.
1669
 * Returns the new task on success, NULL on failure.
1670
 */
1671
static struct dm_task *_new_reload_task(const char *name,
1672
          struct target *head,
1673
          struct target *tail,
1674
          int read_only,
1675
          int secure_data,
1676
          int ima_measurement,
1677
          int major,
1678
          int minor)
1679
0
{
1680
0
  struct dm_task *task;
1681
1682
0
  if (!(task = dm_task_create(DM_DEVICE_RELOAD)))
1683
0
    return_NULL;
1684
1685
0
  if (name && !dm_task_set_name(task, name)) {
1686
0
    dm_task_destroy(task);
1687
0
    return_NULL;
1688
0
  }
1689
1690
0
  task->read_only = read_only;
1691
0
  task->head = head;
1692
0
  task->tail = tail;
1693
0
  task->secure_data = secure_data;
1694
0
  task->ima_measurement = ima_measurement;
1695
0
  task->major = major;
1696
0
  task->minor = minor;
1697
1698
0
  return task;
1699
0
}
1700
1701
/*
1702
 * Revert a failed CREATE-with-table by issuing a synchronous REMOVE.
1703
 * If cookie_set, sets up a udev cookie for the remove.
1704
 * Used by both _create_and_load_v4() and the async create chain.
1705
 */
1706
static void _revert_create(const char *dev_name,
1707
         int cookie_set, uint32_t event_nr)
1708
0
{
1709
0
  struct dm_task *dmt;
1710
0
  uint32_t cookie;
1711
1712
0
  if (!dev_name || !*dev_name)
1713
0
    return;
1714
1715
0
  if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
1716
0
    return;
1717
1718
0
  if (!dm_task_set_name(dmt, dev_name)) {
1719
0
    dm_task_destroy(dmt);
1720
0
    return;
1721
0
  }
1722
1723
0
  if (cookie_set) {
1724
0
    cookie = (event_nr & ~DM_UDEV_FLAGS_MASK) |
1725
0
       (DM_COOKIE_MAGIC << DM_UDEV_FLAGS_SHIFT);
1726
0
    if (!dm_task_set_cookie(dmt, &cookie,
1727
0
          (event_nr & DM_UDEV_FLAGS_MASK) >>
1728
0
          DM_UDEV_FLAGS_SHIFT))
1729
0
      stack; /* keep going */
1730
0
  }
1731
1732
0
  if (!dm_task_run(dmt))
1733
0
    log_error("Failed to revert device creation.");
1734
1735
0
  dm_task_destroy(dmt);
1736
0
}
1737
1738
static int _create_and_load_v4(struct dm_task *dmt)
1739
0
{
1740
0
  struct dm_info info;
1741
0
  struct dm_task *task;
1742
0
  int r, ioctl_errno = 0;
1743
1744
  /* Use new task struct to create the device */
1745
0
  if (!(task = dm_task_create(DM_DEVICE_CREATE))) {
1746
0
    _udev_complete(dmt);
1747
0
    return_0;
1748
0
  }
1749
1750
  /* Copy across relevant fields */
1751
0
  if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name))
1752
0
    goto_bad;
1753
1754
0
  if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid))
1755
0
    goto_bad;
1756
1757
0
  task->major = dmt->major;
1758
0
  task->minor = dmt->minor;
1759
0
  task->uid = dmt->uid;
1760
0
  task->gid = dmt->gid;
1761
0
  task->mode = dmt->mode;
1762
  /* FIXME: Just for udev_check in dm_task_run. Can we avoid this? */
1763
0
  task->event_nr = dmt->event_nr & DM_UDEV_FLAGS_MASK;
1764
0
  task->cookie_set = dmt->cookie_set;
1765
0
  task->add_node = dmt->add_node;
1766
1767
0
  if (!dm_task_run(task)) {
1768
0
    ioctl_errno = task->ioctl_errno;
1769
0
    goto_bad;
1770
0
  }
1771
1772
0
  if (!dm_task_get_info(task, &info) || !info.exists)
1773
0
    goto_bad;
1774
1775
0
  dm_task_destroy(task);
1776
1777
  /* Next load the table */
1778
0
  if (!(task = _new_reload_task(dmt->dev_name, dmt->head, dmt->tail,
1779
0
              dmt->read_only, dmt->secure_data,
1780
0
              dmt->ima_measurement,
1781
0
              info.major, info.minor))) {
1782
0
    stack;
1783
0
    _udev_complete(dmt);
1784
0
    goto revert;
1785
0
  }
1786
1787
0
  r = dm_task_run(task);
1788
0
  if (!r)
1789
0
    ioctl_errno = task->ioctl_errno;
1790
1791
0
  task->head = NULL;
1792
0
  task->tail = NULL;
1793
0
  dm_task_destroy(task);
1794
1795
0
  if (!r) {
1796
0
    stack;
1797
0
    _udev_complete(dmt);
1798
0
    goto revert;
1799
0
  }
1800
1801
  /* Use the original structure last so the info will be correct */
1802
0
  dmt->type = DM_DEVICE_RESUME;
1803
0
  dm_free(dmt->uuid);
1804
0
  dmt->uuid = NULL;
1805
0
  dm_free(dmt->mangled_uuid);
1806
0
  dmt->mangled_uuid = NULL;
1807
  /* coverity[double_free] recursive function call */
1808
0
  _dm_task_free_targets(dmt);
1809
1810
0
  if (dm_task_run(dmt))
1811
0
    return 1;
1812
1813
0
      revert:
1814
0
  _revert_create(dmt->dev_name, dmt->cookie_set, dmt->event_nr);
1815
1816
0
  if (ioctl_errno != 0)
1817
0
    dmt->ioctl_errno =  ioctl_errno;
1818
1819
0
  return 0;
1820
1821
0
      bad:
1822
0
  dm_task_destroy(task);
1823
0
  _udev_complete(dmt);
1824
1825
0
  if (ioctl_errno != 0)
1826
0
    dmt->ioctl_errno =  ioctl_errno;
1827
1828
0
  return 0;
1829
0
}
1830
1831
uint64_t dm_task_get_existing_table_size(const struct dm_task *dmt)
1832
0
{
1833
0
  return dmt->existing_table_size;
1834
0
}
1835
1836
/*
1837
 * Skip "rebuild N" or "write_mostly N" token pair.
1838
 * Old dm-raid may drop these from table output.
1839
 */
1840
static int _skip_raid_volatile_token(const char **pp)
1841
0
{
1842
0
  const char *p = *pp;
1843
1844
0
  if (strncmp(p, "rebuild ", 8) &&
1845
0
      strncmp(p, "write_mostly ", 13))
1846
0
    return 0;
1847
1848
0
  while (*p && *p != ' ')
1849
0
    p++;
1850
0
  if (*p == ' ')
1851
0
    p++;
1852
0
  while (*p && *p != ' ')
1853
0
    p++;
1854
0
  if (*p == ' ')
1855
0
    p++;
1856
1857
0
  *pp = p;
1858
0
  return 1;
1859
0
}
1860
1861
/*
1862
 * Check if raid params are functionally equivalent.
1863
 * p1 = new table, p2 = active table (kernel STATUSTYPE_TABLE).
1864
 *
1865
 * Old dm-raid (< 1.15.1) double-counts rebuild/writemostly in
1866
 * the param count, and early versions drop "rebuild N" from
1867
 * table output once In_sync is set.  Both cause spurious string
1868
 * mismatches that defeat reload suppression.  We skip the param
1869
 * count and ignore volatile "rebuild N" / "write_mostly N" pairs.
1870
 *
1871
 * The 'suspended' flag gates which side gets the volatile skip.
1872
 * Do not simplify this to always-symmetric or always-asymmetric.
1873
 * When NOT suspended, skip only in p2 -- a rebuild in p1 is a
1874
 * deliberate request that must trigger a reload.  When suspended,
1875
 * skip in both p1 and p2 -- LVM is in the second preload pass
1876
 * (the first already loaded the rebuild table via force_reload),
1877
 * the active table is stale, and a redundant reload here would
1878
 * hit "Internal error: table load while devices are suspended".
1879
 */
1880
static int _raid_params_equiv(const char *p1, const char *p2,
1881
            int suspended)
1882
0
{
1883
0
  const char *s1 = strchr(p1, ' ');
1884
0
  const char *s2 = strchr(p2, ' ');
1885
1886
0
  if (!s1 || !s2)
1887
0
    return 0;
1888
1889
  /* Raid personality must match */
1890
0
  if ((s1 - p1) != (s2 - p2) ||
1891
0
      memcmp(p1, p2, s1 - p1))
1892
0
    return 0;
1893
1894
  /* Skip past the param count */
1895
0
  s1 = strchr(s1 + 1, ' ');
1896
0
  s2 = strchr(s2 + 1, ' ');
1897
1898
0
  if (!s1 || !s2)
1899
0
    return 0;
1900
1901
  /* Fast path */
1902
0
  if (!strcmp(s1, s2))
1903
0
    return 1;
1904
1905
0
  s1++;
1906
0
  s2++;
1907
1908
0
  for (;;) {
1909
0
    if (suspended)
1910
0
      while (*s1 && _skip_raid_volatile_token(&s1))
1911
0
        ;
1912
0
    while (*s2 && _skip_raid_volatile_token(&s2))
1913
0
      ;
1914
1915
0
    if (!*s1 && !*s2)
1916
0
      return 1;
1917
1918
0
    if (!*s1 || !*s2)
1919
0
      return 0;
1920
1921
0
    while (*s1 && *s2 && *s1 != ' ' && *s2 != ' ') {
1922
0
      if (*s1 != *s2)
1923
0
        return 0;
1924
0
      s1++;
1925
0
      s2++;
1926
0
    }
1927
1928
0
    if ((*s1 && *s1 != ' ') || (*s2 && *s2 != ' '))
1929
0
      return 0;
1930
1931
0
    if (*s1 == ' ')
1932
0
      s1++;
1933
0
    if (*s2 == ' ')
1934
0
      s2++;
1935
0
  }
1936
0
}
1937
1938
/*
1939
 * Check if integrity params are functionally equivalent.
1940
 * p1 = new table params, p2 = active table params (kernel STATUSTYPE_TABLE).
1941
 *
1942
 * Kernel's integrity table output differs from what LVM emits:
1943
 *
1944
 * - block_size:512 -- LVM always emits, kernel omits when
1945
 *   sectors_per_block==1 (the default).
1946
 *
1947
 * - fix_padding -- LVM always emits, kernel only reports when
1948
 *   SB_FLAG_FIXED_PADDING is set in the on-disk superblock
1949
 *   (written once by initialize_superblock(), NOT on reload).
1950
 *
1951
 * - recalculate -- kernel reports from SB_FLAG_RECALCULATING in the
1952
 *   on-disk superblock, not from the constructor table line.
1953
 *   The kernel NEVER clears this flag; recalc_sector simply advances
1954
 *   past provided_data_sectors.  LVM clears integrity_recalculate in
1955
 *   VG metadata after the first activation (integrity_manip.c), so
1956
 *   subsequent activations omit it from the table line, but the kernel
1957
 *   still reports it from the superblock.  A reload cannot remove the
1958
 *   flag, so treat it as cosmetic in both directions.
1959
 *
1960
 * - kernel may add tokens LVM did not set (buffer_sectors,
1961
 *   journal_watermark, commit_time, etc.)
1962
 *
1963
 * Skipped tokens are listed in _integrity_skip_p1_token().
1964
 * We verify every non-skipped token we emit exists in the kernel output.
1965
 * Extra kernel tokens are acceptable.
1966
 */
1967
1968
/* Tokens LVM emits that the kernel may legitimately omit */
1969
static int _integrity_skip_p1_token(const char *token, unsigned len)
1970
0
{
1971
0
  if (len == 14 && !memcmp(token, "block_size:512", 14))
1972
0
    return 1;
1973
0
  if (len == 11 && !memcmp(token, "fix_padding", 11))
1974
0
    return 1;
1975
0
  if (len == 11 && !memcmp(token, "recalculate", 11))
1976
0
    return 1;
1977
0
  return 0;
1978
0
}
1979
1980
/* Find exact token in a space-separated string */
1981
static int _integrity_has_token(const char *str, const char *token, unsigned len)
1982
0
{
1983
0
  const char *s = str;
1984
1985
0
  while (*s) {
1986
0
    const char *e = s;
1987
0
    while (*e && *e != ' ')
1988
0
      e++;
1989
0
    if ((unsigned)(e - s) == len && !memcmp(s, token, len))
1990
0
      return 1;
1991
0
    s = (*e == ' ') ? e + 1 : e;
1992
0
  }
1993
1994
0
  return 0;
1995
0
}
1996
1997
/* Advance past one space-separated token */
1998
static const char *_skip_one_token(const char *s)
1999
0
{
2000
0
  while (*s && *s != ' ')
2001
0
    s++;
2002
0
  while (*s == ' ')
2003
0
    s++;
2004
0
  return s;
2005
0
}
2006
2007
static int _integrity_params_equiv(const char *p1, const char *p2,
2008
           int suspended __attribute__((unused)))
2009
0
{
2010
0
  const char *s1 = p1, *s2 = p2;
2011
0
  const char *e1, *e2;
2012
0
  const char *args1, *args2;
2013
0
  const char *tok;
2014
0
  unsigned len;
2015
0
  int i;
2016
2017
  /* Compare 4 prefix tokens: dev, start, tag_size, mode */
2018
0
  for (i = 0; i < 4; i++) {
2019
0
    e1 = s1;
2020
0
    while (*e1 && *e1 != ' ')
2021
0
      e1++;
2022
0
    e2 = s2;
2023
0
    while (*e2 && *e2 != ' ')
2024
0
      e2++;
2025
0
    if ((e1 - s1) != (e2 - s2) ||
2026
0
        memcmp(s1, s2, e1 - s1))
2027
0
      return 0;
2028
0
    s1 = (*e1 == ' ') ? e1 + 1 : e1;
2029
0
    s2 = (*e2 == ' ') ? e2 + 1 : e2;
2030
0
  }
2031
2032
  /* Skip param count (5th token) -- differs due to kernel omissions */
2033
0
  args1 = _skip_one_token(s1);
2034
0
  args2 = _skip_one_token(s2);
2035
2036
  /* Fast path */
2037
0
  if (!strcmp(args1, args2))
2038
0
    return 1;
2039
2040
  /* Check every non-skipped token we emit exists in kernel output */
2041
0
  tok = args1;
2042
0
  while (*tok) {
2043
0
    e1 = tok;
2044
0
    while (*e1 && *e1 != ' ')
2045
0
      e1++;
2046
0
    len = (unsigned)(e1 - tok);
2047
0
    if (!_integrity_skip_p1_token(tok, len) &&
2048
0
        !_integrity_has_token(args2, tok, len))
2049
0
      return 0;
2050
0
    tok = (*e1 == ' ') ? e1 + 1 : e1;
2051
0
  }
2052
2053
0
  return 1;
2054
0
}
2055
2056
static int _target_params_equiv(const char *type,
2057
        const char *p1, const char *p2,
2058
        int suspended)
2059
0
{
2060
0
  if (!strcmp(type, "raid"))
2061
0
    return _raid_params_equiv(p1, p2, suspended);
2062
2063
0
  if (!strcmp(type, "integrity"))
2064
0
    return _integrity_params_equiv(p1, p2, suspended);
2065
2066
0
  return 0;
2067
0
}
2068
2069
static int _reload_with_suppression_v4(struct dm_task *dmt)
2070
0
{
2071
0
  struct dm_task *task;
2072
0
  struct target *t1, *t2;
2073
0
  size_t len;
2074
0
  int r;
2075
2076
  /* New task to get existing table information */
2077
0
  if (!(task = dm_task_create(DM_DEVICE_TABLE))) {
2078
0
    log_error("Failed to create device-mapper task struct");
2079
0
    return 0;
2080
0
  }
2081
2082
  /* Copy across relevant fields */
2083
0
  if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
2084
0
    dm_task_destroy(task);
2085
0
    return 0;
2086
0
  }
2087
2088
0
  if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) {
2089
0
    dm_task_destroy(task);
2090
0
    return 0;
2091
0
  }
2092
2093
0
  task->major = dmt->major;
2094
0
  task->minor = dmt->minor;
2095
2096
0
  r = dm_task_run(task);
2097
2098
0
  if (!r) {
2099
0
    dm_task_destroy(task);
2100
0
    return r;
2101
0
  }
2102
2103
  /* Store existing table size */
2104
0
  t2 = task->head;
2105
0
  while (t2 && t2->next)
2106
0
    t2 = t2->next;
2107
0
  dmt->existing_table_size = t2 ? t2->start + t2->length : 0;
2108
2109
0
  if (((task->dmi.v4->flags & DM_READONLY_FLAG) ? 1 : 0) != dmt->read_only)
2110
0
    goto no_match;
2111
2112
0
  t1 = dmt->head;
2113
0
  t2 = task->head;
2114
2115
0
  while (t1 && t2) {
2116
0
    len = strlen(t2->params);
2117
0
    while (len-- > 0 && t2->params[len] == ' ')
2118
0
      t2->params[len] = '\0';
2119
2120
0
    if (t1->start != t2->start) {
2121
0
      log_debug("reload %d:%d diff start %llu %llu type %s %s.", task->major, task->minor,
2122
0
           (unsigned long long)t1->start, (unsigned long long)t2->start, t1->type, t2->type);
2123
0
      goto no_match;
2124
0
    }
2125
0
    if (t1->length != t2->length) {
2126
0
      log_debug("reload %d:%d diff length %llu %llu type %s %s.", task->major, task->minor,
2127
0
          (unsigned long long)t1->length, (unsigned long long)t2->length, t1->type, t2->type);
2128
0
      goto no_match;
2129
0
    }
2130
0
    if (strcmp(t1->type, t2->type)) {
2131
0
      log_debug("reload %d:%d diff type %s %s.", task->major, task->minor, t1->type, t2->type);
2132
0
      goto no_match;
2133
0
    }
2134
0
    if (strcmp(t1->params, t2->params)) {
2135
0
      if (dmt->skip_reload_params_compare) {
2136
0
        log_debug("reload %d:%d diff params ignore for type %s.",
2137
0
            task->major, task->minor, t1->type);
2138
0
        log_debug("reload params1 %s", t1->params);
2139
0
        log_debug("reload params2 %s", t2->params);
2140
0
      } else if (_target_params_equiv(t1->type, t1->params, t2->params,
2141
0
                 task->dmi.v4->flags & DM_SUSPEND_FLAG)) {
2142
0
        log_debug("reload %d:%d diff params equiv for type %s.",
2143
0
            task->major, task->minor, t1->type);
2144
0
        log_debug("reload params1 %s", t1->params);
2145
0
        log_debug("reload params2 %s", t2->params);
2146
0
      } else {
2147
0
        log_debug("reload %d:%d diff params for type %s.",
2148
0
            task->major, task->minor, t1->type);
2149
0
        log_debug("reload params1 %s", t1->params);
2150
0
        log_debug("reload params2 %s", t2->params);
2151
0
        goto no_match;
2152
0
      }
2153
0
    }
2154
2155
0
    t1 = t1->next;
2156
0
    t2 = t2->next;
2157
0
  }
2158
2159
0
  if (!t1 && !t2) {
2160
0
    dmt->dmi.v4 = task->dmi.v4;
2161
0
    task->dmi.v4 = NULL;
2162
0
    dm_task_destroy(task);
2163
0
    return 1;
2164
0
  }
2165
2166
0
no_match:
2167
0
  dm_task_destroy(task);
2168
2169
  /* Now do the original reload */
2170
0
  dmt->suppress_identical_reload = 0;
2171
0
  r = dm_task_run(dmt);
2172
2173
0
  return r;
2174
0
}
2175
2176
static int _check_children_not_suspended_v4(struct dm_task *dmt, uint64_t device)
2177
0
{
2178
0
  struct dm_task *task;
2179
0
  struct dm_info info;
2180
0
  struct dm_deps *deps;
2181
0
  int r = 0;
2182
0
  uint32_t i;
2183
2184
  /* Find dependencies */
2185
0
  if (!(task = dm_task_create(DM_DEVICE_DEPS)))
2186
0
    return 0;
2187
2188
  /* Copy across or set relevant fields */
2189
0
  if (device) {
2190
0
    task->major = MAJOR(device);
2191
0
    task->minor = MINOR(device);
2192
0
  } else {
2193
0
    if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name))
2194
0
      goto out;
2195
2196
0
    if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid))
2197
0
      goto out;
2198
2199
0
    task->major = dmt->major;
2200
0
    task->minor = dmt->minor;
2201
0
  }
2202
2203
0
  task->uid = dmt->uid;
2204
0
  task->gid = dmt->gid;
2205
0
  task->mode = dmt->mode;
2206
  /* FIXME: Just for udev_check in dm_task_run. Can we avoid this? */
2207
0
  task->event_nr = dmt->event_nr & DM_UDEV_FLAGS_MASK;
2208
0
  task->cookie_set = dmt->cookie_set;
2209
0
  task->add_node = dmt->add_node;
2210
2211
0
  if (!(r = dm_task_run(task)))
2212
0
    goto out;
2213
2214
0
  if (!dm_task_get_info(task, &info) || !info.exists)
2215
0
    goto out;
2216
2217
  /*
2218
   * Warn if any of the devices this device depends upon are already
2219
   * suspended: I/O could become trapped between the two devices.
2220
   */
2221
0
  if (info.suspended) {
2222
0
    if (!device)
2223
0
      log_debug_activation("Attempting to suspend a device that is already suspended "
2224
0
               "(%u:%u)", info.major, info.minor);
2225
0
    else
2226
0
      log_error(INTERNAL_ERROR "Attempt to suspend device %s%s%s%.0d%s%.0d%s%s"
2227
0
          "that uses already-suspended device (%u:%u)",
2228
0
          DEV_NAME(dmt) ? : "", DEV_UUID(dmt) ? : "",
2229
0
          dmt->major > 0 ? "(" : "",
2230
0
          dmt->major > 0 ? dmt->major : 0,
2231
0
          dmt->major > 0 ? ":" : "",
2232
0
          dmt->minor > 0 ? dmt->minor : 0,
2233
0
          dmt->major > 0 && dmt->minor == 0 ? "0" : "",
2234
0
          dmt->major > 0 ? ") " : "",
2235
0
          info.major, info.minor);
2236
2237
    /* No need for further recursion */
2238
0
    r = 1;
2239
0
    goto out;
2240
0
  }
2241
2242
0
  if (!(deps = dm_task_get_deps(task)))
2243
0
    goto out;
2244
2245
0
  for (i = 0; i < deps->count; i++) {
2246
    /* Only recurse with dm devices */
2247
0
    if (MAJOR(deps->device[i]) != _dm_device_major)
2248
0
      continue;
2249
2250
0
    if (!_check_children_not_suspended_v4(task, deps->device[i]))
2251
0
      goto out;
2252
0
  }
2253
2254
0
  r = 1;
2255
2256
0
out:
2257
0
  dm_task_destroy(task);
2258
2259
0
  return r;
2260
0
}
2261
2262
static int _suspend_with_validation_v4(struct dm_task *dmt)
2263
0
{
2264
  /* Avoid recursion */
2265
0
  dmt->enable_checks = 0;
2266
2267
  /*
2268
   * Ensure we can't leave any I/O trapped between suspended devices.
2269
   */
2270
0
  if (!_check_children_not_suspended_v4(dmt, 0))
2271
0
    return 0;
2272
2273
  /* Finally, perform the original suspend. */
2274
0
  return dm_task_run(dmt);
2275
0
}
2276
2277
static const char *_sanitise_message(char *message)
2278
0
{
2279
0
  const char *sanitised_message = message ?: "";
2280
2281
  /* FIXME: Check for whitespace variations. */
2282
  /* This traps what cryptsetup sends us. */
2283
0
  if (message && !strncasecmp(message, "key set", 7))
2284
0
    sanitised_message = "key set";
2285
2286
0
  return sanitised_message;
2287
0
}
2288
2289
#ifdef DM_IOCTLS
2290
static int _do_dm_ioctl_unmangle_string(char *str, const char *str_name,
2291
          char *buf, size_t buf_size,
2292
          dm_string_mangling_t mode)
2293
0
{
2294
0
  int r;
2295
2296
0
  if (mode == DM_STRING_MANGLING_NONE)
2297
0
    return 1;
2298
2299
0
  if (!check_multiple_mangled_string_allowed(str, str_name, mode))
2300
0
    return_0;
2301
2302
0
  if ((r = unmangle_string(str, str_name, strlen(str), buf, buf_size, mode)) < 0) {
2303
0
    log_debug_activation("_do_dm_ioctl_unmangle_string: failed to "
2304
0
             "unmangle %s \"%s\"", str_name, str);
2305
0
    return 0;
2306
0
  }
2307
2308
0
  if (r)
2309
0
    memcpy(str, buf, strlen(buf) + 1);
2310
2311
0
  return 1;
2312
0
}
2313
2314
static int _dm_ioctl_unmangle_names(int type, struct dm_ioctl *dmi)
2315
0
{
2316
0
  char buf[DM_NAME_LEN];
2317
0
  char buf_uuid[DM_UUID_LEN];
2318
0
  struct dm_name_list *names;
2319
0
  unsigned next = 0;
2320
0
  char *name;
2321
0
  int r = 1;
2322
0
  uint32_t *event_nr;
2323
0
  char *uuid_ptr;
2324
0
  dm_string_mangling_t mangling_mode = dm_get_name_mangling_mode();
2325
2326
0
  if ((name = dmi->name))
2327
0
    r &= _do_dm_ioctl_unmangle_string(name, "name", buf, sizeof(buf),
2328
0
              mangling_mode);
2329
2330
0
  if (type == DM_DEVICE_LIST &&
2331
0
      ((names = ((struct dm_name_list *) ((char *)dmi + dmi->data_start)))) &&
2332
0
      names->dev) {
2333
0
    do {
2334
0
      names = (struct dm_name_list *)((char *) names + next);
2335
0
      event_nr = _align_ptr(names->name + strlen(names->name) + 1);
2336
0
      r &= _do_dm_ioctl_unmangle_string(names->name, "name",
2337
0
                buf, sizeof(buf), mangling_mode);
2338
      /* Unmangle also UUID within same loop */
2339
0
      if (_check_has_event_nr() &&
2340
0
          (event_nr[1] & DM_NAME_LIST_FLAG_HAS_UUID)) {
2341
0
        uuid_ptr = _align_ptr(event_nr + 2);
2342
0
        r &= _do_dm_ioctl_unmangle_string(uuid_ptr, "UUID", buf_uuid,
2343
0
                  sizeof(buf_uuid), mangling_mode);
2344
0
      }
2345
0
      next = names->next;
2346
0
    } while (next);
2347
0
  }
2348
2349
0
  return r;
2350
0
}
2351
2352
static int _dm_ioctl_unmangle_uuids(int type, struct dm_ioctl *dmi)
2353
0
{
2354
0
  char buf[DM_UUID_LEN];
2355
0
  char *uuid = dmi->uuid;
2356
2357
0
  if (uuid)
2358
0
    return _do_dm_ioctl_unmangle_string(uuid, "UUID", buf, sizeof(buf),
2359
0
                dm_get_name_mangling_mode());
2360
2361
0
  return 1;
2362
0
}
2363
#endif
2364
2365
/* True for ioctl types that generate a udev event and need cookie handling. */
2366
static inline int _dmt_has_uevent(const struct dm_task *dmt)
2367
0
{
2368
0
  return dmt->type == DM_DEVICE_RESUME ||
2369
0
         dmt->type == DM_DEVICE_REMOVE ||
2370
0
         dmt->type == DM_DEVICE_RENAME;
2371
0
}
2372
2373
/*
2374
 * Flatten the task into a fresh dm_ioctl buffer and set all flags and
2375
 * udev cookie bits.  Returns the allocated buffer (caller owns it) or
2376
 * NULL on failure.
2377
 */
2378
static struct dm_ioctl *_dm_task_build_dmi(struct dm_task *dmt,
2379
             unsigned buffer_repeat_count)
2380
0
{
2381
0
  struct dm_ioctl *dmi;
2382
2383
0
  dmi = _flatten(dmt, buffer_repeat_count);
2384
0
  if (!dmi) {
2385
0
    log_error("Couldn't create ioctl argument.");
2386
0
    return NULL;
2387
0
  }
2388
2389
0
  if (dmt->type == DM_DEVICE_TABLE)
2390
0
    dmi->flags |= DM_STATUS_TABLE_FLAG;
2391
2392
0
  dmi->flags |= DM_EXISTS_FLAG; /* FIXME */
2393
2394
0
  if (dmt->no_open_count)
2395
0
    dmi->flags |= DM_SKIP_BDGET_FLAG;
2396
2397
0
  if (_dmt_has_uevent(dmt) && dm_cookie_supported()) {
2398
    /*
2399
     * Always mark events coming from libdevmapper as
2400
     * "primary sourced". This is needed to distinguish
2401
     * any spurious events so we can act appropriately.
2402
     * This needs to be applied even when udev_sync is
2403
     * not used because udev flags could be used alone.
2404
     */
2405
0
    dmi->event_nr |= DM_UDEV_PRIMARY_SOURCE_FLAG <<
2406
0
         DM_UDEV_FLAGS_SHIFT;
2407
2408
    /*
2409
     * Prevent udev vs. libdevmapper race when processing nodes
2410
     * and symlinks. This can happen when the udev rules are
2411
     * installed and udev synchronization code is enabled in
2412
     * libdevmapper but the software using libdevmapper does not
2413
     * make use of it (by not calling dm_task_set_cookie before).
2414
     * We need to instruct the udev rules not to be applied at
2415
     * all in this situation so we can gracefully fallback to
2416
     * libdevmapper's node and symlink creation code.
2417
     */
2418
0
    if (!dmt->cookie_set && dm_udev_get_sync_support()) {
2419
0
      log_debug_activation("Cookie value is not set while trying to call %s "
2420
0
               "ioctl. Please, consider using libdevmapper's udev "
2421
0
               "synchronization interface or disable it explicitly "
2422
0
               "by calling dm_udev_set_sync_support(0).",
2423
0
               dmt->type == DM_DEVICE_RESUME ? "DM_DEVICE_RESUME" :
2424
0
               dmt->type == DM_DEVICE_REMOVE ? "DM_DEVICE_REMOVE" :
2425
0
                       "DM_DEVICE_RENAME");
2426
0
      log_debug_activation("Switching off device-mapper and all subsystem related "
2427
0
               "udev rules. Falling back to libdevmapper node creation.");
2428
      /*
2429
       * Disable general dm and subsystem rules but keep
2430
       * dm disk rules if not flagged out explicitly before.
2431
       * We need /dev/disk content for the software that expects it.
2432
      */
2433
0
      dmi->event_nr |= (DM_UDEV_DISABLE_DM_RULES_FLAG |
2434
0
            DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG) <<
2435
0
           DM_UDEV_FLAGS_SHIFT;
2436
0
    }
2437
0
  }
2438
2439
0
  log_debug_activation("dm %s %s%s %s%s%s %s%.0d%s%.0d%s"
2440
0
           "%s[ %s%s%s%s%s%s%s%s%s%s] %.0" PRIu64 " %s [%u]",
2441
0
           _cmd_data_v4[dmt->type].name,
2442
0
           dmt->new_uuid ? "UUID " : "",
2443
0
           dmi->name, dmi->uuid, dmt->newname ? " " : "",
2444
0
           dmt->newname ? dmt->newname : "",
2445
0
           dmt->major > 0 ? "(" : "",
2446
0
           dmt->major > 0 ? dmt->major : 0,
2447
0
           dmt->major > 0 ? ":" : "",
2448
0
           dmt->minor > 0 ? dmt->minor : 0,
2449
0
           dmt->major > 0 && dmt->minor == 0 ? "0" : "",
2450
0
           dmt->major > 0 ? ") " : "",
2451
0
           dmt->no_open_count ? "noopencount " : "opencount ",
2452
0
           dmt->no_flush ? "noflush " : "flush ",
2453
0
           dmt->read_only ? "readonly " : "",
2454
0
           dmt->skip_lockfs ? "skiplockfs " : "",
2455
0
           dmt->retry_remove ? "retryremove " : "",
2456
0
           dmt->deferred_remove ? "deferredremove " : "",
2457
0
           dmt->secure_data ? "securedata " : "",
2458
0
           dmt->ima_measurement ? "ima_measurement " : "",
2459
0
           dmt->query_inactive_table ? "inactive " : "",
2460
0
           dmt->enable_checks ? "enablechecks " : "",
2461
0
           dmt->sector, _sanitise_message(dmt->message),
2462
0
           dmi->data_size);
2463
2464
0
  return dmi;
2465
0
}
2466
2467
/* Execute a single DM ioctl.  Sets dmt->ioctl_errno on failure.
2468
 * Caller must validate dmt->type via _validate_task_type(). */
2469
int dm_ioctl_exec(int fd, struct dm_task *dmt, struct dm_ioctl *dmi)
2470
0
{
2471
0
  int r;
2472
2473
0
  dmt->ioctl_errno = 0;
2474
2475
0
#ifdef DM_IOCTLS
2476
0
  r = ioctl(fd, _cmd_data_v4[dmt->type].cmd, dmi);
2477
0
  if (r < 0)
2478
0
    dmt->ioctl_errno = errno;
2479
#else /* Userspace alternative for testing */
2480
  r = 0;
2481
#endif
2482
0
  return r;
2483
0
}
2484
2485
/*
2486
 * Execute ioctl with EBUSY retry for remove operations.
2487
 *
2488
 * The dmi buffer is reused across retries without rebuilding.
2489
 * On EBUSY the kernel fails the ioctl early without modifying
2490
 * the dmi structure, so the input fields (name, uuid, dev)
2491
 * remain valid for the next attempt.
2492
 */
2493
static int _dm_ioctl_exec_retry(int fd, struct dm_task *dmt)
2494
0
{
2495
0
  unsigned retries = 0;
2496
0
  int r;
2497
2498
0
  do {
2499
0
    if (retries) {
2500
0
      log_debug_activation("EBUSY retry %u/%u for %s.",
2501
0
               retries, (unsigned) DM_IOCTL_RETRIES,
2502
0
               dmt->dmi.v4->name);
2503
0
      usleep(DM_RETRY_USLEEP_DELAY);
2504
0
    }
2505
2506
0
    r = dm_ioctl_exec(fd, dmt, dmt->dmi.v4);
2507
2508
0
    if (r >= 0)
2509
0
      break;
2510
2511
0
  } while (dmt->retry_remove &&
2512
0
     (dmt->ioctl_errno == EBUSY) &&
2513
0
     (dmt->type == DM_DEVICE_REMOVE) &&
2514
0
     (++retries <= DM_IOCTL_RETRIES));
2515
2516
0
  return r;
2517
0
}
2518
2519
/*
2520
 * Post-ioctl processing: error logging, uevent completion,
2521
 * and name/uuid unmangling.
2522
 * On ioctl error returns 0; caller must call _udev_complete().
2523
 * Calls _udev_complete() only when uevent was not generated by kernel.
2524
 * Returns 1 on success, 0 on failure.
2525
 */
2526
static int _dm_ioctl_post(struct dm_task *dmt, struct dm_ioctl *dmi,
2527
        int r)
2528
0
{
2529
0
#ifdef DM_IOCTLS
2530
0
  if (r < 0 && dmt->expected_errno != dmt->ioctl_errno) {
2531
0
    if (dmt->ioctl_errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) ||
2532
0
              (dmt->type == DM_DEVICE_MKNODES) ||
2533
0
              (dmt->type == DM_DEVICE_STATUS)))
2534
0
      dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */
2535
0
    else {
2536
0
      if (dmt->ioctl_errno == EINTR)
2537
0
        log_verbose("device-mapper: %s ioctl on %s %s%s%.0d%s%.0d%s%s "
2538
0
              "failed: %s",
2539
0
              _cmd_data_v4[dmt->type].name,
2540
0
              dmi->name[0] ? dmi->name : DEV_NAME(dmt) ? : "",
2541
0
              dmi->uuid[0] ? dmi->uuid : DEV_UUID(dmt) ? : "",
2542
0
              dmt->major > 0 ? "(" : "",
2543
0
              dmt->major > 0 ? dmt->major : 0,
2544
0
              dmt->major > 0 ? ":" : "",
2545
0
              dmt->minor > 0 ? dmt->minor : 0,
2546
0
              dmt->major > 0 && dmt->minor == 0 ? "0" : "",
2547
0
              dmt->major > 0 ? ")" : "",
2548
0
              strerror(dmt->ioctl_errno));
2549
0
      else
2550
0
        log_error("device-mapper: %s ioctl on %s %s%s%.0d%s%.0d%s%s "
2551
0
            "failed: %s",
2552
0
            _cmd_data_v4[dmt->type].name,
2553
0
            dmi->name[0] ? dmi->name : DEV_NAME(dmt) ? : "",
2554
0
            dmi->uuid[0] ? dmi->uuid : DEV_UUID(dmt) ? : "",
2555
0
            dmt->major > 0 ? "(" : "",
2556
0
            dmt->major > 0 ? dmt->major : 0,
2557
0
            dmt->major > 0 ? ":" : "",
2558
0
            dmt->minor > 0 ? dmt->minor : 0,
2559
0
            dmt->major > 0 && dmt->minor == 0 ? "0" : "",
2560
0
            dmt->major > 0 ? ")" : "",
2561
0
            strerror(dmt->ioctl_errno));
2562
2563
0
      return 0;
2564
0
    }
2565
0
  }
2566
2567
0
  if (_dmt_has_uevent(dmt) && dm_udev_get_sync_support() &&
2568
0
      !_check_uevent_generated(dmi)) {
2569
0
    if (dmt->deferred_remove)
2570
0
      log_debug_activation("Deferred remove: device busy, "
2571
0
               "no uevent generated.");
2572
0
    else {
2573
0
      log_debug_activation("Uevent not generated! Calling "
2574
0
               "udev_complete internally to "
2575
0
               "avoid process lock-up.");
2576
0
    }
2577
0
    _udev_complete(dmt);
2578
0
  }
2579
2580
0
  if (!_dm_ioctl_unmangle_names(dmt->type, dmi))
2581
0
    return 0;
2582
2583
0
  if (dmt->type != DM_DEVICE_REMOVE &&
2584
0
      !_dm_ioctl_unmangle_uuids(dmt->type, dmi))
2585
0
    return 0;
2586
2587
#else /* Userspace alternative for testing */
2588
  return 0;
2589
#endif
2590
0
  return 1;
2591
0
}
2592
2593
/* Build ioctl buffer, execute it, and post-process the result. */
2594
static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt,
2595
             unsigned buffer_repeat_count)
2596
0
{
2597
0
  struct dm_ioctl *dmi;
2598
0
  int r;
2599
2600
0
  if (!(dmi = _dm_task_build_dmi(dmt, buffer_repeat_count)))
2601
0
    return_NULL;
2602
2603
0
  _dm_zfree_dmi(dmt->dmi.v4);
2604
0
  dmt->dmi.v4 = dmi;
2605
2606
0
  r = _dm_ioctl_exec_retry(_get_control_fd(), dmt);
2607
2608
0
  if (dmt->record_timestamp)
2609
0
    if (!dm_timestamp_get(dmt->ioctl_timestamp))
2610
0
      stack;
2611
2612
0
  if (!_dm_ioctl_post(dmt, dmi, r)) {
2613
0
    _dm_zfree_dmi(dmi);
2614
0
    dmt->dmi.v4 = NULL;
2615
0
    return_NULL;
2616
0
  }
2617
2618
0
  return dmi;
2619
0
}
2620
2621
void dm_task_update_nodes(void)
2622
0
{
2623
0
  update_devs();
2624
0
}
2625
2626
/*
2627
 * Perform device-node operations after a successful ioctl.
2628
 * Returns 1 on success, 0 on failure.
2629
 */
2630
static int _dm_task_node_ops(struct dm_task *dmt, struct dm_ioctl *dmi)
2631
0
{
2632
0
  const char *dev_name = DEV_NAME(dmt);
2633
0
  int check_udev = dmt->cookie_set &&
2634
0
       !(dmt->event_nr >> DM_UDEV_FLAGS_SHIFT &
2635
0
         DM_UDEV_DISABLE_DM_RULES_FLAG);
2636
0
  int rely_on_udev = dmt->cookie_set ? (dmt->event_nr >> DM_UDEV_FLAGS_SHIFT &
2637
0
                DM_UDEV_DISABLE_LIBRARY_FALLBACK) : 0;
2638
2639
0
  switch (dmt->type) {
2640
0
  case DM_DEVICE_CREATE:
2641
0
    if ((dmt->add_node == DM_ADD_NODE_ON_CREATE) &&
2642
0
        dev_name && *dev_name && !rely_on_udev)
2643
0
      add_dev_node(dev_name, MAJOR(dmi->dev),
2644
0
             MINOR(dmi->dev), dmt->uid, dmt->gid,
2645
0
             dmt->mode, check_udev, rely_on_udev);
2646
0
    break;
2647
0
  case DM_DEVICE_REMOVE:
2648
0
    if (dev_name && !rely_on_udev)
2649
0
      rm_dev_node(dev_name, check_udev, rely_on_udev);
2650
0
    break;
2651
2652
0
  case DM_DEVICE_RENAME:
2653
0
    if (!dmt->new_uuid && dev_name)
2654
0
      rename_dev_node(dev_name, dmt->newname,
2655
0
          check_udev, rely_on_udev);
2656
0
    break;
2657
2658
0
  case DM_DEVICE_RESUME:
2659
0
    if (dev_name && *dev_name) {
2660
0
      if (dmt->add_node == DM_ADD_NODE_ON_RESUME)
2661
0
        add_dev_node(dev_name, MAJOR(dmi->dev),
2662
0
               MINOR(dmi->dev), dmt->uid, dmt->gid,
2663
0
               dmt->mode, check_udev, rely_on_udev);
2664
0
      set_dev_node_read_ahead(dev_name,
2665
0
            MAJOR(dmi->dev), MINOR(dmi->dev),
2666
0
            dmt->read_ahead, dmt->read_ahead_flags);
2667
0
    }
2668
0
    break;
2669
2670
0
  case DM_DEVICE_MKNODES:
2671
0
    if (dmi->flags & DM_EXISTS_FLAG)
2672
0
      add_dev_node(dmi->name, MAJOR(dmi->dev),
2673
0
             MINOR(dmi->dev), dmt->uid,
2674
0
             dmt->gid, dmt->mode, 0, rely_on_udev);
2675
0
    else if (dev_name)
2676
0
      rm_dev_node(dev_name, 0, rely_on_udev);
2677
0
    break;
2678
2679
0
  case DM_DEVICE_STATUS:
2680
0
  case DM_DEVICE_TABLE:
2681
0
  case DM_DEVICE_WAITEVENT:
2682
0
    if (!_unmarshal_status(dmt, dmi))
2683
0
      return 0;
2684
0
    break;
2685
0
  }
2686
2687
0
  return 1;
2688
0
}
2689
2690
int dm_task_get_errno(struct dm_task *dmt)
2691
0
{
2692
0
  return dmt->ioctl_errno;
2693
0
}
2694
2695
/*
2696
 * Check whether a DM_BUFFER_FULL_FLAG retry is allowed for this task type.
2697
 * Increments the global doubling factor on success.
2698
 * Returns 1 if the caller should retry with a larger buffer, 0 otherwise.
2699
 */
2700
static int _can_retry_buffer_full(struct dm_task *dmt)
2701
0
{
2702
0
  switch (dmt->type) {
2703
0
  case DM_DEVICE_LIST_VERSIONS:
2704
0
  case DM_DEVICE_LIST:
2705
0
  case DM_DEVICE_DEPS:
2706
0
  case DM_DEVICE_STATUS:
2707
0
  case DM_DEVICE_TABLE:
2708
0
  case DM_DEVICE_WAITEVENT:
2709
0
  case DM_DEVICE_TARGET_MSG:
2710
0
    break;
2711
0
  default:
2712
0
    log_error("libdevmapper buffer too small for data.");
2713
0
    return 0;
2714
0
  }
2715
2716
0
  if (_ioctl_buffer_double_factor >= DM_IOCTL_BUFFER_MAX_DOUBLINGS) {
2717
0
    log_error("Ioctl buffer maximum reached (16KB << %u = %zu bytes), giving up.",
2718
0
        _ioctl_buffer_double_factor,
2719
0
        (size_t)16 * 1024 << _ioctl_buffer_double_factor);
2720
0
    return 0;
2721
0
  }
2722
2723
0
  _ioctl_buffer_double_factor++;
2724
2725
0
  return 1;
2726
0
}
2727
2728
#if defined(GNU_SYMVER)
2729
/*
2730
 * Enforce new version 1_02_197 of dm_task_run() that propagates
2731
 * ioctl() errno is being linked to app.
2732
 */
2733
DM_EXPORT_SYMBOL_BASE(dm_task_run)
2734
int dm_task_run_base(struct dm_task *dmt);
2735
int dm_task_run_base(struct dm_task *dmt)
2736
0
{
2737
0
  return dm_task_run(dmt);
2738
0
}
2739
#endif
2740
2741
DM_EXPORT_NEW_SYMBOL(int, dm_task_run, 1_02_197)
2742
  (struct dm_task *dmt)
2743
0
{
2744
0
  struct dm_ioctl *dmi;
2745
0
  int suspended_counter;
2746
0
  const char *dev_name = DEV_NAME(dmt);
2747
0
  const char *dev_uuid = DEV_UUID(dmt);
2748
2749
0
  if (!_validate_task_type(dmt))
2750
0
    return_0;
2751
2752
  /* Old-style creation had a table supplied */
2753
0
  if (dmt->type == DM_DEVICE_CREATE && dmt->head)
2754
0
    return _create_and_load_v4(dmt);
2755
2756
0
  if (dmt->type == DM_DEVICE_MKNODES && !dev_name &&
2757
0
      !dev_uuid && dmt->major <= 0)
2758
0
    return _mknodes_v4(dmt);
2759
2760
0
  if ((dmt->type == DM_DEVICE_RELOAD) && dmt->suppress_identical_reload)
2761
0
    return _reload_with_suppression_v4(dmt);
2762
2763
0
  if ((dmt->type == DM_DEVICE_SUSPEND) && dmt->enable_checks)
2764
0
    return _suspend_with_validation_v4(dmt);
2765
2766
0
  if (!_open_control()) {
2767
0
    _udev_complete(dmt);
2768
0
    return_0;
2769
0
  }
2770
2771
0
  if ((suspended_counter = dm_get_suspended_counter()) &&
2772
0
      dmt->type == DM_DEVICE_RELOAD)
2773
0
    log_error(INTERNAL_ERROR "Performing unsafe table load while %d device(s) "
2774
0
        "are known to be suspended: "
2775
0
        "%s%s%s %s%.0d%s%.0d%s%s",
2776
0
        suspended_counter,
2777
0
        dev_name ? : "",
2778
0
        dev_uuid ? " UUID " : "",
2779
0
        dev_uuid ? : "",
2780
0
        dmt->major > 0 ? "(" : "",
2781
0
        dmt->major > 0 ? dmt->major : 0,
2782
0
        dmt->major > 0 ? ":" : "",
2783
0
        dmt->minor > 0 ? dmt->minor : 0,
2784
0
        dmt->major > 0 && dmt->minor == 0 ? "0" : "",
2785
0
        dmt->major > 0 ? ") " : "");
2786
2787
  /* FIXME Detect and warn if cookie set but should not be. */
2788
0
repeat_ioctl:
2789
0
  if (!(dmi = _do_dm_ioctl(dmt, _ioctl_buffer_double_factor))) {
2790
0
    _udev_complete(dmt);
2791
0
    return_0;
2792
0
  }
2793
2794
0
  if (dmi->flags & DM_BUFFER_FULL_FLAG) {
2795
0
    if (_can_retry_buffer_full(dmt))
2796
0
      goto repeat_ioctl;
2797
2798
0
    goto_bad;
2799
0
  }
2800
2801
0
  if (!_dm_task_node_ops(dmt, dmi))
2802
0
    goto_bad;
2803
2804
0
  return 1;
2805
2806
0
      bad:
2807
0
  _dm_zfree_dmi(dmt->dmi.v4);
2808
0
  dmt->dmi.v4 = NULL;
2809
0
  return 0;
2810
0
}
2811
2812
void dm_hold_control_dev(int hold_open)
2813
0
{
2814
0
  pthread_mutex_lock(&_control_fd_mutex);
2815
0
  _hold_control_fd_open = hold_open ? 1 : 0;
2816
0
  pthread_mutex_unlock(&_control_fd_mutex);
2817
2818
0
  log_debug("Hold of control device is now %sset.",
2819
0
      hold_open ? "" : "un");
2820
0
}
2821
2822
void dm_lib_release(void)
2823
5.42k
{
2824
5.42k
  pthread_mutex_lock(&_control_fd_mutex);
2825
5.42k
  if (!_hold_control_fd_open)
2826
5.42k
    _close_control_fd();
2827
5.42k
  pthread_mutex_unlock(&_control_fd_mutex);
2828
2829
5.42k
  update_devs();
2830
5.42k
}
2831
2832
void dm_pools_check_leaks(void);
2833
2834
static pthread_once_t _exit_once = PTHREAD_ONCE_INIT;
2835
2836
static void _do_lib_exit(void)
2837
0
{
2838
0
  int suspended_counter;
2839
2840
0
  if ((suspended_counter = dm_get_suspended_counter()))
2841
0
    log_error("libdevmapper exiting with %d device(s) still suspended.", suspended_counter);
2842
2843
0
  dm_lib_release();
2844
0
  selinux_release();
2845
0
  pthread_mutex_lock(&_control_fd_mutex);
2846
0
  if (_dm_bitset)
2847
0
    dm_bitset_destroy(_dm_bitset);
2848
0
  _dm_bitset = NULL;
2849
0
  pthread_mutex_unlock(&_control_fd_mutex);
2850
0
  dm_pools_check_leaks();
2851
0
  dm_dump_memory();
2852
0
}
2853
2854
void dm_lib_exit(void)
2855
0
{
2856
0
  pthread_once(&_exit_once, _do_lib_exit);
2857
0
}
2858
2859
#if defined(GNU_SYMVER)
2860
/*
2861
 * Maintain binary backward compatibility.
2862
 * Version script mechanism works with 'gcc' compatible compilers only.
2863
 */
2864
2865
/*
2866
 * This following code is here to retain ABI compatibility after adding
2867
 * the field deferred_remove to struct dm_info in version 1.02.89.
2868
 *
2869
 * Binaries linked against version 1.02.88 of libdevmapper or earlier
2870
 * will use this function that returns dm_info without the
2871
 * deferred_remove field.
2872
 *
2873
 * Binaries compiled against version 1.02.89 onwards will use
2874
 * the new function dm_task_get_info_with_deferred_remove due to the
2875
 * #define.
2876
 *
2877
 * N.B. Keep this function at the end of the file to make sure that
2878
 * no code in this file accidentally calls it.
2879
 */
2880
2881
DM_EXPORT_SYMBOL_BASE(dm_task_get_info)
2882
int dm_task_get_info_base(struct dm_task *dmt, struct dm_info *info);
2883
int dm_task_get_info_base(struct dm_task *dmt, struct dm_info *info)
2884
0
{
2885
0
  struct dm_info new_info;
2886
2887
0
  if (!dm_task_get_info(dmt, &new_info))
2888
0
    return 0;
2889
2890
0
  memcpy(info, &new_info, offsetof(struct dm_info, deferred_remove));
2891
2892
0
  return 1;
2893
0
}
2894
2895
#endif
2896
2897
int dm_task_get_info_with_deferred_remove(struct dm_task *dmt, struct dm_info *info);
2898
int dm_task_get_info_with_deferred_remove(struct dm_task *dmt, struct dm_info *info)
2899
0
{
2900
0
  struct dm_info new_info;
2901
2902
0
  if (!dm_task_get_info(dmt, &new_info))
2903
0
    return 0;
2904
2905
0
  memcpy(info, &new_info, offsetof(struct dm_info, internal_suspend));
2906
2907
0
  return 1;
2908
0
}