Coverage Report

Created: 2026-09-13 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/lvm2/libdm/libdm-common.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3
 * Copyright (C) 2004-2025 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/ioctl/libdm-targets.h"
18
#include "libdm-common.h"
19
#include "libdm/misc/kdev_t.h"
20
#include "libdm/misc/dm-ioctl.h"
21
22
#include <stdarg.h>
23
#include <pthread.h>
24
#include <sys/param.h>
25
#include <sys/ioctl.h>
26
#include <fcntl.h>
27
#include <dirent.h>
28
29
#ifdef UDEV_SYNC_SUPPORT
30
#  include <sys/types.h>
31
#  include <sys/ipc.h>
32
#  include <sys/sem.h>
33
#  include <libudev.h>
34
#endif
35
36
#ifdef __linux__
37
#  include <linux/fs.h>
38
#endif
39
40
#ifdef HAVE_SELINUX
41
#  include <selinux/selinux.h>
42
#endif
43
#ifdef HAVE_SELINUX_LABEL_H
44
#  include <selinux/label.h>
45
#endif
46
47
2
#define DM_DEFAULT_NAME_MANGLING_MODE_ENV_VAR_NAME "DM_DEFAULT_NAME_MANGLING_MODE"
48
49
0
#define DEV_DIR "/dev/"
50
51
#ifdef UDEV_SYNC_SUPPORT
52
#ifdef _SEM_SEMUN_UNDEFINED
53
union semun
54
{
55
  int val;      /* value for SETVAL */
56
  struct semid_ds *buf;   /* buffer for IPC_STAT & IPC_SET */
57
  unsigned short int *array;  /* array for GETALL & SETALL */
58
  struct seminfo *__buf;    /* buffer for IPC_INFO */
59
};
60
#endif
61
#endif
62
63
static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR;
64
static char _sysfs_dir[PATH_MAX] = "/sys/";
65
static const char _mountinfo[] = "/proc/self/mountinfo";
66
67
0
#define DM_MAX_UUID_PREFIX_LEN  15
68
static char _default_uuid_prefix[DM_MAX_UUID_PREFIX_LEN + 1] = "LVM-";
69
70
static int _verbose = 0;
71
static int _suspended_dev_counter = 0;
72
static dm_string_mangling_t _name_mangling_mode = DEFAULT_DM_NAME_MANGLING;
73
74
#ifdef HAVE_SELINUX_LABEL_H
75
static struct selabel_handle *_selabel_handle = NULL;
76
static pthread_once_t _selabel_once = PTHREAD_ONCE_INIT;
77
78
static void _init_selabel_handle(void)
79
{
80
  _selabel_handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
81
}
82
83
static struct selabel_handle *_get_selabel_handle(void)
84
{
85
  pthread_once(&_selabel_once, _init_selabel_handle);
86
87
  return _selabel_handle;
88
}
89
#endif
90
91
/* Set once in dm_lib_init(), immutable after -- safe for concurrent reads */
92
static int _udev_disabled = 0;
93
94
/* Thread that called dm_lib_init() -- only this thread may call set-once setters */
95
static pthread_t _init_tid;
96
97
static int _is_init_thread(const char *action)
98
21.2k
{
99
21.2k
  if (pthread_equal(pthread_self(), _init_tid))
100
21.2k
    return 1;
101
102
0
  log_warn("WARNING: Only main thread can %s.", action);
103
104
0
  return 0;
105
21.2k
}
106
107
#ifdef UDEV_SYNC_SUPPORT
108
static int _semaphore_supported = 0;
109
static int _udev_running = 0;
110
#endif
111
112
static pthread_once_t _lib_init_once = PTHREAD_ONCE_INIT;
113
114
static void _do_lib_init(void)
115
2
{
116
2
  const char *env;
117
118
2
  _init_tid = pthread_self();
119
120
2
  if (getenv("DM_DISABLE_UDEV"))
121
0
    _udev_disabled = 1;
122
123
2
  _name_mangling_mode = DEFAULT_DM_NAME_MANGLING;
124
2
  if ((env = getenv(DM_DEFAULT_NAME_MANGLING_MODE_ENV_VAR_NAME))) {
125
0
    if (!strcasecmp(env, "none"))
126
0
      _name_mangling_mode = DM_STRING_MANGLING_NONE;
127
0
    else if (!strcasecmp(env, "auto"))
128
0
      _name_mangling_mode = DM_STRING_MANGLING_AUTO;
129
0
    else if (!strcasecmp(env, "hex"))
130
0
      _name_mangling_mode = DM_STRING_MANGLING_HEX;
131
0
  }
132
2
}
133
134
void dm_lib_init(void)
135
2
{
136
2
  pthread_once(&_lib_init_once, _do_lib_init);
137
2
}
138
139
static void _dm_lib_init(void) __attribute__((constructor));
140
141
static void _dm_lib_init(void)
142
2
{
143
2
  dm_lib_init();
144
2
}
145
146
/*
147
 * Library users can provide their own logging
148
 * function.
149
 */
150
151
static int _abort_on_internal_errors = 0;
152
static int _debug_with_line_numbers = 0;
153
static pthread_once_t _log_env_once = PTHREAD_ONCE_INIT;
154
155
static void _init_log_env_vars(void)
156
0
{
157
0
  _abort_on_internal_errors =
158
0
    strcmp(getenv("DM_ABORT_ON_INTERNAL_ERRORS") ? : "0", "0");
159
0
  _debug_with_line_numbers =
160
0
    strcmp(getenv("DM_DEBUG_WITH_LINE_NUMBERS") ? : "0", "0");
161
0
}
162
163
__attribute__((format(printf, 5, 0)))
164
static void _default_log_line(int level, const char *file,
165
            int line, int dm_errno_or_class,
166
            const char *f, va_list ap)
167
0
{
168
0
  FILE *out = log_stderr(level) ? stderr : stdout;
169
170
0
  pthread_once(&_log_env_once, _init_log_env_vars);
171
172
0
  level = log_level(level);
173
174
0
  if (level <= _LOG_WARN || _verbose) {
175
0
    if (level < _LOG_WARN)
176
0
      out = stderr;
177
178
0
    if (_debug_with_line_numbers)
179
0
      fprintf(out, "%s:%d     ", file, line);
180
181
0
    vfprintf(out, f, ap);
182
0
    fputc('\n', out);
183
0
  }
184
185
0
  if (_abort_on_internal_errors &&
186
0
      !strncmp(f, INTERNAL_ERROR, sizeof(INTERNAL_ERROR) - 1))
187
0
    abort();
188
0
}
189
190
__attribute__((format(printf, 5, 6)))
191
static void _default_log_with_errno(int level,
192
      const char *file, int line, int dm_errno_or_class,
193
      const char *f, ...)
194
0
{
195
0
  va_list ap;
196
197
0
  va_start(ap, f);
198
0
  _default_log_line(level, file, line, dm_errno_or_class, f, ap);
199
0
  va_end(ap);
200
0
}
201
202
__attribute__((format(printf, 4, 5)))
203
static void _default_log(int level, const char *file,
204
       int line, const char *f, ...)
205
0
{
206
0
  va_list ap;
207
208
0
  va_start(ap, f);
209
0
  _default_log_line(level, file, line, 0, f, ap);
210
0
  va_end(ap);
211
0
}
212
213
dm_log_fn dm_log = _default_log;
214
dm_log_with_errno_fn dm_log_with_errno = _default_log_with_errno;
215
216
/*
217
 * Wrapper function to reformat new messages to and
218
 * old style logging which had not used errno parameter
219
 *
220
 * As we cannot simply pass '...' to old function we
221
 * need to process arg list locally and just pass '%s' + buffer
222
 */
223
__attribute__((format(printf, 5, 6)))
224
static void _log_to_default_log(int level,
225
      const char *file, int line, int dm_errno_or_class,
226
      const char *f, ...)
227
0
{
228
0
  int n;
229
0
  va_list ap;
230
0
  char buf[2 * PATH_MAX + 256]; /* big enough for most messages */
231
232
0
  va_start(ap, f);
233
0
  n = vsnprintf(buf, sizeof(buf), f, ap);
234
0
  va_end(ap);
235
236
0
  if (n > 0) /* Could be truncated */
237
0
    dm_log(level, file, line, "%s", buf);
238
0
}
239
240
/*
241
 * Wrapper function take 'old' style message without errno
242
 * and log it via new logging function with errno arg
243
 *
244
 * This minor case may happen if new libdm is used with old
245
 * recompiled tool that would decided to use new logging,
246
 * but still would like to use old binary plugins.
247
 */
248
__attribute__((format(printf, 4, 5)))
249
static void _log_to_default_log_with_errno(int level,
250
      const char *file, int line, const char *f, ...)
251
0
{
252
0
  int n;
253
0
  va_list ap;
254
0
  char buf[2 * PATH_MAX + 256]; /* big enough for most messages */
255
256
0
  va_start(ap, f);
257
0
  n = vsnprintf(buf, sizeof(buf), f, ap);
258
0
  va_end(ap);
259
260
0
  if (n > 0) /* Could be truncated */
261
0
    dm_log_with_errno(level, file, line, 0, "%s", buf);
262
0
}
263
264
void dm_log_init(dm_log_fn fn)
265
10.6k
{
266
10.6k
  if (fn ? (dm_log == fn) : !dm_log_is_non_default())
267
0
    return;
268
269
10.6k
  if (!_is_init_thread("set log function"))
270
0
    return;
271
272
10.6k
  if (fn)  {
273
5.30k
    dm_log = fn;
274
5.30k
    dm_log_with_errno = _log_to_default_log;
275
5.30k
  } else {
276
5.30k
    dm_log = _default_log;
277
5.30k
    dm_log_with_errno = _default_log_with_errno;
278
5.30k
  }
279
10.6k
}
280
281
int dm_log_is_non_default(void)
282
5.30k
{
283
5.30k
  return (dm_log == _default_log && dm_log_with_errno == _default_log_with_errno) ? 0 : 1;
284
5.30k
}
285
286
void dm_log_with_errno_init(dm_log_with_errno_fn fn)
287
0
{
288
0
  if (fn ? (dm_log_with_errno == fn) : !dm_log_is_non_default())
289
0
    return;
290
291
0
  if (!_is_init_thread("set log function"))
292
0
    return;
293
294
0
  if (fn) {
295
0
    dm_log = _log_to_default_log_with_errno;
296
0
    dm_log_with_errno = fn;
297
0
  } else {
298
0
    dm_log = _default_log;
299
0
    dm_log_with_errno = _default_log_with_errno;
300
0
  }
301
0
}
302
303
void dm_log_init_verbose(int level)
304
10.6k
{
305
10.6k
  if (_verbose == level)
306
0
    return;
307
308
10.6k
  if (!_is_init_thread("set log verbose level"))
309
0
    return;
310
311
10.6k
  _verbose = level;
312
10.6k
}
313
314
static int _build_dev_path(char *buffer, size_t len, const char *dev_name)
315
0
{
316
0
  int r;
317
318
  /* If there's a /, assume caller knows what they're doing */
319
0
  if (strchr(dev_name, '/'))
320
0
    r = dm_strncpy(buffer, dev_name, len);
321
0
  else
322
0
    r = (dm_snprintf(buffer, len, "%s/%s",
323
0
         _dm_dir, dev_name) < 0) ? 0 : 1;
324
0
  if (!r)
325
0
    log_error("Failed to build dev path for \"%s\".", dev_name);
326
327
0
  return r;
328
0
}
329
330
int dm_get_library_version(char *version, size_t size)
331
0
{
332
0
  return dm_strncpy(version, DM_LIB_VERSION, size);
333
0
}
334
335
void inc_suspended(void)
336
0
{
337
0
  _suspended_dev_counter++;
338
0
  log_debug_activation("Suspended device counter increased to %d", _suspended_dev_counter);
339
0
}
340
341
void dec_suspended(void)
342
0
{
343
0
  if (!_suspended_dev_counter) {
344
0
    log_error("Attempted to decrement suspended device counter below zero.");
345
0
    return;
346
0
  }
347
348
0
  _suspended_dev_counter--;
349
0
  log_debug_activation("Suspended device counter reduced to %d", _suspended_dev_counter);
350
0
}
351
352
int dm_get_suspended_counter(void)
353
0
{
354
0
  return _suspended_dev_counter;
355
0
}
356
357
int dm_set_name_mangling_mode(dm_string_mangling_t name_mangling_mode)
358
0
{
359
0
  if (_name_mangling_mode == name_mangling_mode)
360
0
    return 1;
361
362
0
  if (_is_init_thread("change mangling mode"))
363
0
    _name_mangling_mode = name_mangling_mode;
364
365
0
  return 1;
366
0
}
367
368
dm_string_mangling_t dm_get_name_mangling_mode(void)
369
0
{
370
0
  return _name_mangling_mode;
371
0
}
372
373
struct dm_task *dm_task_create(int type)
374
0
{
375
0
  struct dm_task *dmt = dm_zalloc(sizeof(*dmt));
376
377
0
  if (!dmt) {
378
0
    log_error("dm_task_create: dm_zalloc(%" PRIsize_t ") failed",
379
0
        sizeof(*dmt));
380
0
    return NULL;
381
0
  }
382
383
  /* DM_DEVICE_VERSION is the task that performs the version check itself */
384
0
  if (type != DM_DEVICE_VERSION && !dm_check_version()) {
385
0
    dm_free(dmt);
386
0
    return_NULL;
387
0
  }
388
389
0
  dmt->type = type;
390
0
  dmt->minor = -1;
391
0
  dmt->major = -1;
392
0
  dmt->allow_default_major_fallback = 1;
393
0
  dmt->uid = DM_DEVICE_UID;
394
0
  dmt->gid = DM_DEVICE_GID;
395
0
  dmt->mode = DM_DEVICE_MODE;
396
0
  dmt->no_open_count = 0;
397
0
  dmt->read_ahead = DM_READ_AHEAD_AUTO;
398
0
  dmt->read_ahead_flags = 0;
399
0
  dmt->event_nr = 0;
400
0
  dmt->cookie_set = 0;
401
0
  dmt->query_inactive_table = 0;
402
0
  dmt->new_uuid = 0;
403
0
  dmt->secure_data = 0;
404
0
  dmt->record_timestamp = 0;
405
0
  dmt->ima_measurement = 0;
406
407
0
  return dmt;
408
0
}
409
410
/*
411
 * Find the name associated with a given device number by scanning _dm_dir.
412
 */
413
static int _find_dm_name_of_device(dev_t st_rdev, char *buf, size_t buf_len)
414
0
{
415
0
  const char *name;
416
0
  char path[PATH_MAX];
417
0
  struct dirent *dirent;
418
0
  DIR *d;
419
0
  struct stat st;
420
0
  int r = 0;
421
422
0
  if (!(d = opendir(_dm_dir))) {
423
0
    log_sys_error("opendir", _dm_dir);
424
0
    return 0;
425
0
  }
426
427
0
  while ((dirent = readdir(d))) {
428
0
    name = dirent->d_name;
429
430
0
    if (!strcmp(name, ".") || !strcmp(name, ".."))
431
0
      continue;
432
433
0
    if (dm_snprintf(path, sizeof(path), "%s/%s", _dm_dir,
434
0
        name) == -1) {
435
0
      log_error("Couldn't create path for %s", name);
436
0
      continue;
437
0
    }
438
439
0
    if (stat(path, &st))
440
0
      continue;
441
442
0
    if (st.st_rdev == st_rdev) {
443
0
      dm_strncpy(buf, name, buf_len);
444
0
      r = 1;
445
0
      break;
446
0
    }
447
0
  }
448
449
0
  if (closedir(d))
450
0
    log_sys_debug("closedir", _dm_dir);
451
452
0
  return r;
453
0
}
454
455
static int _is_whitelisted_char(char c)
456
0
{
457
  /*
458
   * Actually, DM supports any character in a device name.
459
   * This whitelist is just for proper integration with udev.
460
   */
461
0
  if ((c >= '0' && c <= '9') ||
462
0
      (c >= 'A' && c <= 'Z') ||
463
0
      (c >= 'a' && c <= 'z') ||
464
0
      strchr("#+-.:=@_", c) != NULL)
465
0
    return 1;
466
467
0
  return 0;
468
0
}
469
470
int check_multiple_mangled_string_allowed(const char *str, const char *str_name,
471
           dm_string_mangling_t mode)
472
0
{
473
0
  if (mode == DM_STRING_MANGLING_AUTO && strstr(str, "\\x5cx")) {
474
0
    log_error("The %s \"%s\" seems to be mangled more than once. "
475
0
        "This is not allowed in auto mode.", str_name, str);
476
0
    return 0;
477
0
  }
478
479
0
  return 1;
480
0
}
481
482
/*
483
 * Mangle all characters in the input string which are not on a whitelist
484
 * with '\xNN' format where NN is the hex value of the character.
485
 */
486
int mangle_string(const char *str, const char *str_name, size_t len,
487
      char *buf, size_t buf_len, dm_string_mangling_t mode)
488
0
{
489
0
  int need_mangling = -1; /* -1 don't know yet, 0 no, 1 yes */
490
0
  size_t i, j;
491
492
0
  if (!str || !buf)
493
0
    return -1;
494
495
  /* Is there anything to do at all? */
496
0
  if (!*str || !len)
497
0
    return 0;
498
499
0
  if (buf_len < DM_NAME_LEN) {
500
0
    log_error(INTERNAL_ERROR "mangle_string: supplied buffer too small");
501
0
    return -1;
502
0
  }
503
504
0
  if (mode == DM_STRING_MANGLING_NONE)
505
0
    mode = DM_STRING_MANGLING_AUTO;
506
507
0
  for (i = 0, j = 0; str[i]; i++) {
508
0
    if (mode == DM_STRING_MANGLING_AUTO) {
509
      /*
510
       * Detect already mangled part of the string and keep it.
511
       * Return error on mixture of mangled/not mangled!
512
       */
513
0
      if (str[i] == '\\' && str[i+1] == 'x') {
514
0
        if ((len - i < 4) || (need_mangling == 1))
515
0
          goto bad1;
516
0
        if (buf_len - j < 4)
517
0
          goto bad2;
518
519
0
        memcpy(&buf[j], &str[i], 4);
520
0
        i+=3; j+=4;
521
522
0
        need_mangling = 0;
523
0
        continue;
524
0
      }
525
0
    }
526
527
0
    if (_is_whitelisted_char(str[i])) {
528
      /* whitelisted, keep it. */
529
0
      if (buf_len - j < 1)
530
0
        goto bad2;
531
0
      buf[j] = str[i];
532
0
      j++;
533
0
    } else {
534
      /*
535
       * Not on a whitelist, mangle it.
536
       * Return error on mixture of mangled/not mangled
537
       * unless a DM_STRING_MANGLING_HEX is used!.
538
       */
539
0
      if ((mode != DM_STRING_MANGLING_HEX) && (need_mangling == 0))
540
0
        goto bad1;
541
0
      if (buf_len - j < 4)
542
0
        goto bad2;
543
544
0
      (void) sprintf(&buf[j], "\\x%02x", (unsigned char) str[i]);
545
0
      j+=4;
546
547
0
      need_mangling = 1;
548
0
    }
549
0
  }
550
551
0
  if (buf_len - j < 1)
552
0
    goto bad2;
553
0
  buf[j] = '\0';
554
555
  /* All chars in the string whitelisted? */
556
0
  if (need_mangling == -1)
557
0
    need_mangling = 0;
558
559
0
  return need_mangling;
560
561
0
bad1:
562
0
  log_error("The %s \"%s\" contains mixed mangled and unmangled "
563
0
      "characters or it's already mangled improperly.", str_name, str);
564
0
  return -1;
565
0
bad2:
566
0
  log_error("Mangled form of the %s too long for \"%s\".", str_name, str);
567
0
  return -1;
568
0
}
569
570
/*
571
 * Try to unmangle supplied string.
572
 * Return value: -1 on error, 0 when no unmangling needed, 1 when unmangling applied
573
 */
574
int unmangle_string(const char *str, const char *str_name, size_t len,
575
        char *buf, size_t buf_len, dm_string_mangling_t mode)
576
0
{
577
0
  int strict = mode != DM_STRING_MANGLING_NONE;
578
0
  char str_rest[DM_NAME_LEN + 1];
579
0
  size_t i, j;
580
0
  unsigned int code;
581
0
  int r = 0;
582
583
0
  if (!str || !buf)
584
0
    return -1;
585
586
  /* Is there anything to do at all? */
587
0
  if (!*str || !len)
588
0
    return 0;
589
590
0
  if (buf_len < DM_NAME_LEN) {
591
0
    log_error(INTERNAL_ERROR "unmangle_string: supplied buffer too small");
592
0
    return -1;
593
0
  }
594
595
0
  for (i = 0, j = 0; str[i]; i++, j++) {
596
0
    if (strict && !(_is_whitelisted_char(str[i]) || str[i]=='\\')) {
597
0
      log_error("The %s \"%s\" should be mangled but "
598
0
          "it contains blacklisted characters.", str_name, str);
599
0
      j=0; r=-1;
600
0
      goto out;
601
0
    }
602
603
0
    if (str[i] == '\\' && str[i+1] == 'x') {
604
0
      if ((len - i < 4) ||
605
0
          !sscanf(&str[i+2], "%2x%" DM_TO_STRING(DM_NAME_LEN) "s",
606
0
            &code, str_rest)) {
607
0
        log_debug_activation("Hex encoding mismatch detected in %s \"%s\" "
608
0
                 "while trying to unmangle it.", str_name, str);
609
0
        goto out;
610
0
      }
611
0
      buf[j] = (unsigned char) code;
612
613
      /* skip the encoded part we've just decoded! */
614
0
      i+= 3;
615
616
      /* unmangling applied */
617
0
      r = 1;
618
0
    } else
619
0
      buf[j] = str[i];
620
0
  }
621
622
0
out:
623
0
  buf[j] = '\0';
624
0
  return r;
625
0
}
626
627
static int _dm_task_set_name(struct dm_task *dmt, const char *name,
628
           dm_string_mangling_t mangling_mode)
629
0
{
630
0
  char mangled_name[DM_NAME_LEN];
631
0
  int r = 0;
632
633
0
  dm_free(dmt->dev_name);
634
0
  dmt->dev_name = NULL;
635
0
  dm_free(dmt->mangled_dev_name);
636
0
  dmt->mangled_dev_name = NULL;
637
638
0
  if (strlen(name) >= DM_NAME_LEN) {
639
0
    log_error("Name \"%s\" too long.", name);
640
0
    return 0;
641
0
  }
642
643
0
  if (!check_multiple_mangled_string_allowed(name, "name", mangling_mode))
644
0
    return_0;
645
646
0
  if (mangling_mode != DM_STRING_MANGLING_NONE &&
647
0
      (r = mangle_string(name, "name", strlen(name), mangled_name,
648
0
             sizeof(mangled_name), mangling_mode)) < 0) {
649
0
    log_error("Failed to mangle device name \"%s\".", name);
650
0
    return 0;
651
0
  }
652
653
  /* Store mangled_dev_name only if it differs from dev_name! */
654
0
  if (r) {
655
0
    log_debug_activation("Device name mangled [%s]: %s --> %s",
656
0
             mangling_mode == DM_STRING_MANGLING_AUTO ? "auto" : "hex",
657
0
             name, mangled_name);
658
0
    if (!(dmt->mangled_dev_name = dm_strdup(mangled_name))) {
659
0
      log_error("_dm_task_set_name: dm_strdup(%s) failed", mangled_name);
660
0
      return 0;
661
0
    }
662
0
  }
663
664
0
  if (!(dmt->dev_name = dm_strdup(name))) {
665
0
    log_error("_dm_task_set_name: dm_strdup(%s) failed", name);
666
0
    return 0;
667
0
  }
668
669
0
  return 1;
670
0
}
671
672
static int _dm_task_set_name_from_path(struct dm_task *dmt, const char *path,
673
               const char *name)
674
0
{
675
0
  char buf[PATH_MAX];
676
0
  struct stat st1, st2;
677
0
  const char *final_name = NULL;
678
0
  size_t len;
679
680
0
  if (dmt->type == DM_DEVICE_CREATE) {
681
0
    log_error("Name \"%s\" invalid. It contains \"/\".", path);
682
0
    return 0;
683
0
  }
684
685
0
  if (!stat(path, &st1)) {
686
    /*
687
     * Found directly.
688
     * If supplied path points to same device as last component
689
     * under /dev/mapper, use that name directly.
690
     */
691
0
    if (dm_snprintf(buf, sizeof(buf), "%s/%s", _dm_dir, name) == -1) {
692
0
      log_error("Couldn't create path for %s", name);
693
0
      return 0;
694
0
    }
695
696
0
    if (!stat(buf, &st2) && (st1.st_rdev == st2.st_rdev))
697
0
      final_name = name;
698
0
  } else {
699
    /* Not found. */
700
    /* If there is exactly one '/' try a prefix of /dev */
701
0
    if ((len = strlen(path)) < 3 || path[0] == '/' ||
702
0
        dm_count_chars(path, len, '/') != 1) {
703
0
      log_error("Device %s not found", path);
704
0
      return 0;
705
0
    }
706
0
    if (dm_snprintf(buf, sizeof(buf), "%s/../%s", _dm_dir, path) == -1) {
707
0
      log_error("Couldn't create /dev path for %s", path);
708
0
      return 0;
709
0
    }
710
0
    if (stat(buf, &st1)) {
711
0
      log_error("Device %s not found", path);
712
0
      return 0;
713
0
    }
714
    /* Found */
715
0
  }
716
717
  /*
718
   * If we don't have the dm name yet, Call _find_dm_name_of_device() to
719
   * scan _dm_dir for a match.
720
   */
721
0
  if (!final_name) {
722
0
    if (_find_dm_name_of_device(st1.st_rdev, buf, sizeof(buf)))
723
0
      final_name = buf;
724
0
    else {
725
0
      log_error("Device %s not found", name);
726
0
      return 0;
727
0
    }
728
0
  }
729
730
  /* This is an already existing path - do not mangle! */
731
0
  return _dm_task_set_name(dmt, final_name, DM_STRING_MANGLING_NONE);
732
0
}
733
734
int dm_task_set_name(struct dm_task *dmt, const char *name)
735
0
{
736
0
  const char *pos;
737
738
  /* Path supplied for existing device? */
739
0
  if ((pos = strrchr(name, '/')))
740
0
    return _dm_task_set_name_from_path(dmt, name, pos + 1);
741
742
0
  return _dm_task_set_name(dmt, name, dm_get_name_mangling_mode());
743
0
}
744
745
const char *dm_task_get_name(const struct dm_task *dmt)
746
0
{
747
0
  return (dmt->dmi.v4->name);
748
0
}
749
750
static char *_task_get_string_mangled(const char *str, const char *str_name,
751
              char *buf, size_t buf_size,
752
              dm_string_mangling_t mode)
753
0
{
754
0
  char *rs;
755
0
  int r;
756
757
0
  if ((r = mangle_string(str, str_name, strlen(str), buf, buf_size, mode)) < 0)
758
0
    return NULL;
759
760
0
  if (!(rs = r ? dm_strdup(buf) : dm_strdup(str)))
761
0
    log_error("_task_get_string_mangled: dm_strdup failed");
762
763
0
  return rs;
764
0
}
765
766
static char *_task_get_string_unmangled(const char *str, const char *str_name,
767
          char *buf, size_t buf_size,
768
          dm_string_mangling_t mode)
769
0
{
770
0
  char *rs;
771
0
  int r = 0;
772
773
  /*
774
   * Unless the mode used is 'none', the string
775
   * is *already* unmangled on ioctl return!
776
   */
777
0
  if (mode == DM_STRING_MANGLING_NONE &&
778
0
      (r = unmangle_string(str, str_name, strlen(str), buf, buf_size, mode)) < 0)
779
0
    return NULL;
780
781
0
  if (!(rs = r ? dm_strdup(buf) : dm_strdup(str)))
782
0
    log_error("_task_get_string_unmangled: dm_strdup failed");
783
784
0
  return rs;
785
0
}
786
787
char *dm_task_get_name_mangled(const struct dm_task *dmt)
788
0
{
789
0
  const char *s = dm_task_get_name(dmt);
790
0
  char buf[DM_NAME_LEN];
791
0
  char *rs;
792
793
0
  if (!(rs = _task_get_string_mangled(s, "name", buf, sizeof(buf), dm_get_name_mangling_mode())))
794
0
    log_error("Failed to mangle device name \"%s\".", s);
795
796
0
  return rs;
797
0
}
798
799
char *dm_task_get_name_unmangled(const struct dm_task *dmt)
800
0
{
801
0
  const char *s = dm_task_get_name(dmt);
802
0
  char buf[DM_NAME_LEN];
803
0
  char *rs;
804
805
0
  if (!(rs = _task_get_string_unmangled(s, "name", buf, sizeof(buf), dm_get_name_mangling_mode())))
806
0
    log_error("Failed to unmangle device name \"%s\".", s);
807
808
0
  return rs;
809
0
}
810
811
const char *dm_task_get_uuid(const struct dm_task *dmt)
812
0
{
813
0
  return (dmt->dmi.v4->uuid);
814
0
}
815
816
char *dm_task_get_uuid_mangled(const struct dm_task *dmt)
817
0
{
818
0
  const char *s = dm_task_get_uuid(dmt);
819
0
  char buf[DM_UUID_LEN];
820
0
  char *rs;
821
822
0
  if (!(rs = _task_get_string_mangled(s, "UUID", buf, sizeof(buf), dm_get_name_mangling_mode())))
823
0
    log_error("Failed to mangle device uuid \"%s\".", s);
824
825
0
  return rs;
826
0
}
827
828
char *dm_task_get_uuid_unmangled(const struct dm_task *dmt)
829
0
{
830
0
  const char *s = dm_task_get_uuid(dmt);
831
0
  char buf[DM_UUID_LEN];
832
0
  char *rs;
833
834
0
  if (!(rs = _task_get_string_unmangled(s, "UUID", buf, sizeof(buf), dm_get_name_mangling_mode())))
835
0
    log_error("Failed to unmangle device uuid \"%s\".", s);
836
837
0
  return rs;
838
0
}
839
840
int dm_task_set_newname(struct dm_task *dmt, const char *newname)
841
0
{
842
0
  dm_string_mangling_t mangling_mode = dm_get_name_mangling_mode();
843
0
  char mangled_name[DM_NAME_LEN];
844
0
  int r = 0;
845
846
0
  if (strchr(newname, '/')) {
847
0
    log_error("Name \"%s\" invalid. It contains \"/\".", newname);
848
0
    return 0;
849
0
  }
850
851
0
  if (strlen(newname) >= DM_NAME_LEN) {
852
0
    log_error("Name \"%s\" too long", newname);
853
0
    return 0;
854
0
  }
855
856
0
  if (!*newname) {
857
0
    log_error("Non empty new name is required.");
858
0
    return 0;
859
0
  }
860
861
0
  if (!check_multiple_mangled_string_allowed(newname, "new name", mangling_mode))
862
0
    return_0;
863
864
0
  if (mangling_mode != DM_STRING_MANGLING_NONE &&
865
0
      (r = mangle_string(newname, "new name", strlen(newname), mangled_name,
866
0
             sizeof(mangled_name), mangling_mode)) < 0) {
867
0
    log_error("Failed to mangle new device name \"%s\"", newname);
868
0
    return 0;
869
0
  }
870
871
0
  if (r) {
872
0
    log_debug_activation("New device name mangled [%s]: %s --> %s",
873
0
             mangling_mode == DM_STRING_MANGLING_AUTO ? "auto" : "hex",
874
0
             newname, mangled_name);
875
0
    newname = mangled_name;
876
0
  }
877
878
0
  dm_free(dmt->newname);
879
0
  if (!(dmt->newname = dm_strdup(newname))) {
880
0
    log_error("dm_task_set_newname: dm_strdup(%s) failed", newname);
881
0
    return 0;
882
0
  }
883
884
0
  dmt->new_uuid = 0;
885
886
0
  return 1;
887
0
}
888
889
int dm_task_set_uuid(struct dm_task *dmt, const char *uuid)
890
0
{
891
0
  char mangled_uuid[DM_UUID_LEN];
892
0
  dm_string_mangling_t mangling_mode = dm_get_name_mangling_mode();
893
0
  int r = 0;
894
895
0
  dm_free(dmt->uuid);
896
0
  dmt->uuid = NULL;
897
0
  dm_free(dmt->mangled_uuid);
898
0
  dmt->mangled_uuid = NULL;
899
900
0
  if (!check_multiple_mangled_string_allowed(uuid, "UUID", mangling_mode))
901
0
    return_0;
902
903
0
  if (mangling_mode != DM_STRING_MANGLING_NONE &&
904
0
      (r = mangle_string(uuid, "UUID", strlen(uuid), mangled_uuid,
905
0
             sizeof(mangled_uuid), mangling_mode)) < 0) {
906
0
    log_error("Failed to mangle device uuid \"%s\".", uuid);
907
0
    return 0;
908
0
  }
909
910
0
  if (r) {
911
0
    log_debug_activation("Device uuid mangled [%s]: %s --> %s",
912
0
             mangling_mode == DM_STRING_MANGLING_AUTO ? "auto" : "hex",
913
0
             uuid, mangled_uuid);
914
915
0
    if (!(dmt->mangled_uuid = dm_strdup(mangled_uuid))) {
916
0
      log_error("dm_task_set_uuid: dm_strdup(%s) failed", mangled_uuid);
917
0
      return 0;
918
0
    }
919
0
  }
920
921
0
  if (!(dmt->uuid = dm_strdup(uuid))) {
922
0
    log_error("dm_task_set_uuid: dm_strdup(%s) failed", uuid);
923
0
    return 0;
924
0
  }
925
926
0
  return 1;
927
0
}
928
929
int dm_task_set_major(struct dm_task *dmt, int major)
930
0
{
931
0
  dmt->major = major;
932
0
  dmt->allow_default_major_fallback = 0;
933
934
0
  return 1;
935
0
}
936
937
int dm_task_set_minor(struct dm_task *dmt, int minor)
938
0
{
939
0
  dmt->minor = minor;
940
941
0
  return 1;
942
0
}
943
944
int dm_task_set_major_minor(struct dm_task *dmt, int major, int minor,
945
          int allow_default_major_fallback)
946
0
{
947
0
  dmt->major = major;
948
0
  dmt->minor = minor;
949
0
  dmt->allow_default_major_fallback = allow_default_major_fallback;
950
951
0
  return 1;
952
0
}
953
954
int dm_task_set_uid(struct dm_task *dmt, uid_t uid)
955
0
{
956
0
  dmt->uid = uid;
957
958
0
  return 1;
959
0
}
960
961
int dm_task_set_gid(struct dm_task *dmt, gid_t gid)
962
0
{
963
0
  dmt->gid = gid;
964
965
0
  return 1;
966
0
}
967
968
int dm_task_set_mode(struct dm_task *dmt, mode_t mode)
969
0
{
970
0
  dmt->mode = mode;
971
972
0
  return 1;
973
0
}
974
975
int dm_task_enable_checks(struct dm_task *dmt)
976
0
{
977
0
  dmt->enable_checks = 1;
978
979
0
  return 1;
980
0
}
981
982
int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size,
983
           const char *ttype, const char *params)
984
0
{
985
0
  struct target *t = create_target(start, size, ttype, params);
986
0
  if (!t)
987
0
    return_0;
988
989
0
  if (!dmt->head)
990
0
    dmt->head = dmt->tail = t;
991
0
  else {
992
0
    dmt->tail->next = t;
993
0
    dmt->tail = t;
994
0
  }
995
996
0
  return 1;
997
0
}
998
999
#ifdef HAVE_SELINUX
1000
static int _selabel_lookup(const char *path, mode_t mode,
1001
         char **scontext)
1002
{
1003
#ifdef HAVE_SELINUX_LABEL_H
1004
  if (!_get_selabel_handle()) {
1005
    log_error("selabel_open failed: %s", strerror(errno));
1006
    return 0;
1007
  }
1008
1009
  if (selabel_lookup(_get_selabel_handle(), scontext, path, mode)) {
1010
    log_debug_activation("selabel_lookup failed for %s: %s",
1011
             path, strerror(errno));
1012
    return 0;
1013
  }
1014
#else
1015
  if (matchpathcon(path, mode, scontext)) {
1016
    log_debug_activation("matchpathcon failed for %s: %s",
1017
             path, strerror(errno));
1018
    return 0;
1019
  }
1020
#endif
1021
  return 1;
1022
}
1023
#endif
1024
1025
#ifdef HAVE_SELINUX
1026
static int _selinux_enabled;
1027
static pthread_once_t _selinux_enabled_once = PTHREAD_ONCE_INIT;
1028
1029
static void _init_selinux_enabled(void)
1030
{
1031
  _selinux_enabled = is_selinux_enabled();
1032
}
1033
1034
static int _is_selinux_enabled(void)
1035
{
1036
  pthread_once(&_selinux_enabled_once, _init_selinux_enabled);
1037
1038
  return _selinux_enabled;
1039
}
1040
#endif
1041
1042
int dm_prepare_selinux_context(const char *path, mode_t mode)
1043
0
{
1044
#ifdef HAVE_SELINUX
1045
  char *scontext = NULL;
1046
1047
  if (_is_selinux_enabled() <= 0)
1048
    return 1;
1049
1050
  if (path) {
1051
    if (!_selabel_lookup(path, mode, &scontext))
1052
      return_0;
1053
1054
    log_debug_activation("Preparing SELinux context for %s to %s.", path, scontext);
1055
  }
1056
  else
1057
    log_debug_activation("Resetting SELinux context to default value.");
1058
1059
  if (setfscreatecon(scontext) < 0) {
1060
    log_sys_error("setfscreatecon", (path ? : "SELinux context reset"));
1061
    freecon(scontext);
1062
    return 0;
1063
  }
1064
1065
  freecon(scontext);
1066
#endif
1067
0
  return 1;
1068
0
}
1069
1070
int dm_set_selinux_context(const char *path, mode_t mode)
1071
0
{
1072
#ifdef HAVE_SELINUX
1073
  char *scontext = NULL;
1074
1075
  if (_is_selinux_enabled() <= 0)
1076
    return 1;
1077
1078
  if (!_selabel_lookup(path, mode, &scontext))
1079
    return_0;
1080
1081
  log_debug_activation("Setting SELinux context for %s to %s.", path, scontext);
1082
1083
  if ((lsetfilecon(path, scontext) < 0) && (errno != ENOTSUP)) {
1084
    log_sys_error("lsetfilecon", path);
1085
    freecon(scontext);
1086
    return 0;
1087
  }
1088
1089
  freecon(scontext);
1090
#endif
1091
0
  return 1;
1092
0
}
1093
1094
void selinux_release(void)
1095
0
{
1096
#ifdef HAVE_SELINUX_LABEL_H
1097
  if (_selabel_handle)
1098
    selabel_close(_selabel_handle);
1099
  _selabel_handle = NULL;
1100
#endif
1101
0
}
1102
1103
static int _warn_if_op_needed(int warn_if_udev_failed)
1104
0
{
1105
0
  return warn_if_udev_failed && dm_udev_get_sync_support() && dm_udev_get_checking();
1106
0
}
1107
1108
static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
1109
       uid_t uid, gid_t gid, mode_t mode, int warn_if_udev_failed)
1110
0
{
1111
0
  char path[PATH_MAX];
1112
0
  struct stat info;
1113
0
  struct stat linfo;
1114
0
  dev_t dev = MKDEV(major, minor);
1115
0
  mode_t old_mask;
1116
1117
0
  if (!_build_dev_path(path, sizeof(path), dev_name))
1118
0
    return_0;
1119
1120
  /*
1121
   * Check if the device node already exists.
1122
   * Note: stat() follows symlinks, so this checks the target device,
1123
   * not the symlink itself. This works correctly for both real nodes
1124
   * and symlinks pointing to the right device.
1125
   */
1126
0
  if (stat(path, &info) >= 0) {
1127
0
    if (!S_ISBLK(info.st_mode)) {
1128
0
      log_error("A non-block device file at '%s' "
1129
0
          "is already present", path);
1130
0
      return 0;
1131
0
    }
1132
1133
    /* If right inode already exists we don't touch uid etc. */
1134
0
    if (info.st_rdev == dev) {
1135
      /*
1136
       * Correct device exists (either as real node or symlink).
1137
       * Use lstat() to distinguish between them for logging.
1138
       */
1139
0
      if (lstat(path, &linfo) >= 0 && S_ISLNK(linfo.st_mode))
1140
0
        log_debug_activation("Symlink %s to correct device already exists", path);
1141
0
      return 1;
1142
0
    }
1143
1144
    /* Wrong device exists, remove it before creating correct one */
1145
    /* coverity[toctou] stat check is for validation; ENOENT is handled */
1146
0
    if (unlink(path) && (errno != ENOENT)) {
1147
0
      log_sys_error("unlink", path);
1148
0
      return 0;
1149
0
    }
1150
0
  } else {
1151
    /*
1152
     * stat() failed. Check for dangling symlinks (where lstat succeeds
1153
     * but stat fails with ENOENT because the symlink target doesn't exist).
1154
     * Remove the dangling symlink before attempting to create a new node.
1155
     */
1156
0
    if (errno == ENOENT && lstat(path, &linfo) >= 0 && S_ISLNK(linfo.st_mode)) {
1157
0
      log_debug_activation("Removing dangling symlink %s", path);
1158
      /* coverity[toctou] lstat check is only for logging; ENOENT is handled */
1159
0
      if (unlink(path) && (errno != ENOENT)) {
1160
0
        log_sys_error("unlink", path);
1161
0
        return 0;
1162
0
      }
1163
0
    }
1164
0
    if (_warn_if_op_needed(warn_if_udev_failed))
1165
0
      log_warn("%s not set up by udev: Falling back to direct "
1166
0
         "node creation.", path);
1167
0
  }
1168
1169
  /*
1170
   * Test environment optimization: If using alternative dev dir (e.g., /tmp/LVMTEST/dev)
1171
   * and the real /dev node already exists, create a symlink instead of a duplicate node.
1172
   * This ensures operations trigger udev events which only monitors /dev.
1173
   * Requires cookie support (DM >= 4.15) for udev sync; on older kernels
1174
   * udev may transiently delete /dev/dm-N nodes, breaking the symlinks.
1175
   */
1176
0
  if (dm_cookie_supported() && strcmp(_dm_dir, DEV_DIR) != 0) {
1177
0
    char real_path[PATH_MAX];
1178
0
    struct stat real_stat;
1179
1180
    /* Build path to real /dev node (kernel always creates /dev/dm-N) */
1181
0
    if (dm_snprintf(real_path, sizeof(real_path), DEV_DIR "dm-%u", minor) >= 0) {
1182
      /* Check if real node exists with matching dev */
1183
0
      if (stat(real_path, &real_stat) >= 0 &&
1184
0
          S_ISBLK(real_stat.st_mode) &&
1185
0
          real_stat.st_rdev == dev) {
1186
        /*
1187
         * Real /dev/dm-N exists. Create symlink from alternative location.
1188
         * This allows operations to work through the symlink and trigger
1189
         * udev events on the real device.
1190
         */
1191
0
        log_debug_activation("Creating symlink %s -> %s", path, real_path);
1192
0
        (void) dm_prepare_selinux_context(path, S_IFLNK);
1193
0
        if (symlink(real_path, path) < 0) {
1194
0
          log_sys_error("symlink", path);
1195
0
          (void) dm_prepare_selinux_context(NULL, 0);
1196
0
          return 0;
1197
0
        }
1198
0
        (void) dm_prepare_selinux_context(NULL, 0);
1199
0
        log_debug_activation("Created symlink %s -> %s", path, real_path);
1200
0
        return 1;
1201
0
      }
1202
0
    }
1203
0
  }
1204
1205
0
  (void) dm_prepare_selinux_context(path, S_IFBLK);
1206
0
  old_mask = umask(0);
1207
1208
  /* The node may already have been created by udev. So ignore EEXIST. */
1209
  /* coverity[toctou] previous checks are for cleanup/optimization; EEXIST is handled */
1210
0
  if (mknod(path, S_IFBLK | mode, dev) < 0 && errno != EEXIST) {
1211
0
    log_error("%s: mknod for %s failed: %s", path, dev_name, strerror(errno));
1212
0
    umask(old_mask);
1213
0
    (void) dm_prepare_selinux_context(NULL, 0);
1214
0
    return 0;
1215
0
  }
1216
0
  umask(old_mask);
1217
0
  (void) dm_prepare_selinux_context(NULL, 0);
1218
1219
0
  if (chown(path, uid, gid) < 0) {
1220
0
    log_sys_error("chown", path);
1221
0
    return 0;
1222
0
  }
1223
1224
0
  log_debug_activation("Created %s", path);
1225
1226
0
  return 1;
1227
0
}
1228
1229
static int _rm_dev_node(const char *dev_name, int warn_if_udev_failed)
1230
0
{
1231
0
  char path[PATH_MAX];
1232
0
  struct stat info;
1233
1234
0
  if (!_build_dev_path(path, sizeof(path), dev_name))
1235
0
    return_0;
1236
0
  if (lstat(path, &info) < 0)
1237
0
    return 1;
1238
0
  else if (_warn_if_op_needed(warn_if_udev_failed))
1239
0
    log_warn("Node %s was not removed by udev. "
1240
0
       "Falling back to direct node removal.", path);
1241
1242
  /* udev may already have deleted the node. Ignore ENOENT. */
1243
  /* coverity[toctou] lstat is only for the warning; ENOENT is handled */
1244
0
  if (unlink(path) && (errno != ENOENT)) {
1245
0
    log_sys_error("unlink", path);
1246
0
    return 0;
1247
0
  }
1248
1249
0
  log_debug_activation("Removed %s", path);
1250
1251
0
  return 1;
1252
0
}
1253
1254
static int _rename_dev_node(const char *old_name, const char *new_name,
1255
          int warn_if_udev_failed)
1256
0
{
1257
0
  char oldpath[PATH_MAX];
1258
0
  char newpath[PATH_MAX];
1259
0
  struct stat info, info2;
1260
0
  struct stat *info_block_dev;
1261
1262
0
  if (!_build_dev_path(oldpath, sizeof(oldpath), old_name) ||
1263
0
      !_build_dev_path(newpath, sizeof(newpath), new_name))
1264
0
    return_0;
1265
1266
0
  if (lstat(newpath, &info) == 0) {
1267
0
    if (S_ISLNK(info.st_mode)) {
1268
0
      if (stat(newpath, &info2) == 0)
1269
0
        info_block_dev = &info2;
1270
0
      else {
1271
0
        log_sys_error("stat", newpath);
1272
0
        return 0;
1273
0
      }
1274
0
    } else
1275
0
      info_block_dev = &info;
1276
1277
0
    if (!S_ISBLK(info_block_dev->st_mode)) {
1278
0
      log_error("A non-block device file at '%s' "
1279
0
          "is already present", newpath);
1280
0
      return 0;
1281
0
    }
1282
0
    else if (_warn_if_op_needed(warn_if_udev_failed)) {
1283
0
      if (lstat(oldpath, &info) < 0 &&
1284
0
         errno == ENOENT)
1285
        /* assume udev already deleted this */
1286
0
        return 1;
1287
1288
0
      log_warn("The node %s should have been renamed to %s "
1289
0
         "by udev but old node is still present. "
1290
0
         "Falling back to direct old node removal.",
1291
0
         oldpath, newpath);
1292
0
      return _rm_dev_node(old_name, 0);
1293
0
    }
1294
1295
    /* Remove existing node at target path before rename */
1296
    /* coverity[toctou] stat/lstat checks are for validation; errors are handled */
1297
0
    if (unlink(newpath) < 0) {
1298
0
      if (errno == EPERM) {
1299
        /* devfs, entry has already been renamed */
1300
0
        return 1;
1301
0
      }
1302
0
      log_error("Unable to unlink device node for '%s'",
1303
0
          new_name);
1304
0
      return 0;
1305
0
    }
1306
0
  }
1307
0
  else if (_warn_if_op_needed(warn_if_udev_failed))
1308
0
    log_warn("The node %s should have been renamed to %s "
1309
0
       "by udev but new node is not present. "
1310
0
       "Falling back to direct node rename.",
1311
0
       oldpath, newpath);
1312
1313
  /* udev may already have renamed the node. Ignore ENOENT. */
1314
  /* FIXME: when renaming to target mangling mode "none" with udev
1315
   * while there are some blacklisted characters in the node name,
1316
   * udev will remove the old_node, but fails to properly rename
1317
   * to new_node. The libdevmapper code tries to call
1318
   * rename(old_node,new_node), but that won't do anything
1319
   * since the old node is already removed by udev.
1320
   * For example renaming 'a\x20b' to 'a b':
1321
   *   - udev removes 'a\x20b'
1322
   *   - udev creates 'a' and 'b' (since it considers the ' ' as a delimiter
1323
   *   - libdevmapper checks udev has done the rename properly
1324
   *   - libdevmapper calls stat(new_node) and it does not see it
1325
   *   - libdevmapper calls rename(old_node,new_node)
1326
   *   - the rename is a NOP since the old_node does not exist anymore
1327
   *
1328
   * However, this situation is very rare - why would anyone need
1329
   * to rename to an unsupported mode??? So a fix for this would be
1330
   * just for completeness.
1331
   */
1332
0
  if (rename(oldpath, newpath) < 0 && errno != ENOENT) {
1333
0
    log_error("Unable to rename device node from '%s' to '%s'",
1334
0
        old_name, new_name);
1335
0
    return 0;
1336
0
  }
1337
1338
0
  log_debug_activation("Renamed %s to %s", oldpath, newpath);
1339
1340
0
  return 1;
1341
0
}
1342
1343
#ifdef __linux__
1344
static int _open_dev_node(const char *dev_name)
1345
0
{
1346
0
  int fd = -1;
1347
0
  char path[PATH_MAX];
1348
1349
0
  if (!_build_dev_path(path, sizeof(path), dev_name))
1350
0
    return fd;
1351
1352
0
  if ((fd = open(path, O_RDONLY, 0)) < 0)
1353
0
    log_sys_error("open", path);
1354
1355
0
  return fd;
1356
0
}
1357
1358
int get_dev_node_read_ahead(const char *dev_name, uint32_t major, uint32_t minor,
1359
          uint32_t *read_ahead)
1360
0
{
1361
0
  char path0[PATH_MAX];
1362
0
  char buf[24];
1363
0
  int len;
1364
0
  int r = 1;
1365
0
  int fd;
1366
0
  long read_ahead_long = 0;
1367
1368
  /*
1369
   * If we know the device number, use sysfs if we can.
1370
   * Otherwise use BLKRAGET ioctl.
1371
   */
1372
0
  if (*_sysfs_dir && major != 0) {
1373
0
    if (dm_snprintf(path0, sizeof(path0), "%sdev/block/%" PRIu32
1374
0
        ":%" PRIu32 "/bdi/read_ahead_kb", _sysfs_dir,
1375
0
        major, minor) < 0) {
1376
0
      log_error("Failed to build sysfs_path.");
1377
0
      return 0;
1378
0
    }
1379
1380
0
    if ((fd = open(path0, O_RDONLY, 0)) != -1) {
1381
      /* Reading from sysfs, expecting number\n */
1382
0
      if ((len = read(fd, buf, sizeof(buf) - 1)) < 1) {
1383
0
        log_sys_error("read", path0);
1384
0
        r = 0;
1385
0
      } else {
1386
0
        buf[len] = 0; /* kill \n and ensure \0 */
1387
0
        *read_ahead = atoi(buf) * 2;
1388
0
        log_debug_activation("%s (%u:%u): read ahead is %u.",
1389
0
                 dev_name, major, minor, *read_ahead);
1390
0
      }
1391
1392
0
      if (close(fd))
1393
0
        log_sys_debug("close", path0);
1394
1395
0
      return r;
1396
0
    }
1397
1398
0
    log_sys_debug("open", path0);
1399
    /* Fall back to use dev_name */
1400
0
  }
1401
1402
  /*
1403
   * Open/close dev_name may block the process
1404
   * (i.e. overfilled thin pool volume)
1405
   */
1406
0
  if (!*dev_name) {
1407
0
    log_error("Empty device name passed to BLKRAGET");
1408
0
    return 0;
1409
0
  }
1410
1411
0
  if ((fd = _open_dev_node(dev_name)) < 0)
1412
0
    return_0;
1413
1414
0
  if (ioctl(fd, BLKRAGET, &read_ahead_long)) {
1415
0
    log_sys_error("BLKRAGET", dev_name);
1416
0
    *read_ahead = 0;
1417
0
    r = 0;
1418
0
  } else {
1419
0
    *read_ahead = (uint32_t) read_ahead_long;
1420
0
    log_debug_activation("%s: read ahead is %" PRIu32, dev_name, *read_ahead);
1421
0
  }
1422
1423
0
  if (close(fd))
1424
0
    log_sys_debug("close", dev_name);
1425
1426
0
  return r;
1427
0
}
1428
1429
static int _set_read_ahead(const char *dev_name, uint32_t major, uint32_t minor,
1430
         uint32_t read_ahead)
1431
0
{
1432
0
  char path0[PATH_MAX];
1433
0
  char buf[24];
1434
0
  int len;
1435
0
  int r = 1;
1436
0
  int fd;
1437
0
  long read_ahead_long = (long) read_ahead;
1438
1439
0
  log_debug_activation("%s (%u:%u): Setting read ahead to %u.",
1440
0
           dev_name, major, minor, read_ahead);
1441
1442
  /*
1443
   * If we know the device number, use sysfs if we can.
1444
   * Otherwise use BLKRASET ioctl. RA is set after resume.
1445
   */
1446
0
  if (*_sysfs_dir && major != 0) {
1447
0
    if (dm_snprintf(path0, sizeof(path0), "%sdev/block/%" PRIu32
1448
0
        ":%" PRIu32 "/bdi/read_ahead_kb",
1449
0
        _sysfs_dir, major, minor) < 0) {
1450
0
      log_error("Failed to build sysfs_path.");
1451
0
      return 0;
1452
0
    }
1453
1454
    /* Sysfs is kB based, round up to kB */
1455
0
    if ((len = dm_snprintf(buf, sizeof(buf), FMTu32,
1456
0
               (read_ahead + 1) / 2)) < 0) {
1457
0
      log_error("Failed to build size in kB.");
1458
0
      return 0;
1459
0
    }
1460
1461
0
    if ((fd = open(path0, O_WRONLY, 0)) != -1) {
1462
0
      if (write(fd, buf, len) < len) {
1463
0
        log_sys_error("write", path0);
1464
0
        r = 0;
1465
0
      }
1466
1467
0
      if (close(fd))
1468
0
        log_sys_debug("close", path0);
1469
1470
0
      return r;
1471
0
    }
1472
1473
0
    log_sys_debug("open", path0);
1474
    /* Fall back to use dev_name */
1475
0
  }
1476
1477
0
  if (!*dev_name) {
1478
0
    log_error("Empty device name passed to BLKRASET.");
1479
0
    return 0;
1480
0
  }
1481
1482
0
  if ((fd = _open_dev_node(dev_name)) < 0)
1483
0
    return_0;
1484
1485
0
  if (ioctl(fd, BLKRASET, read_ahead_long)) {
1486
0
    log_sys_error("BLKRASET", dev_name);
1487
0
    r = 0;
1488
0
  }
1489
1490
0
  if (close(fd))
1491
0
    log_sys_debug("close", dev_name);
1492
1493
0
  return r;
1494
0
}
1495
1496
static int _set_dev_node_read_ahead(const char *dev_name,
1497
            uint32_t major, uint32_t minor,
1498
            uint32_t read_ahead, uint32_t read_ahead_flags)
1499
0
{
1500
0
  uint32_t current_read_ahead;
1501
1502
0
  if (read_ahead == DM_READ_AHEAD_AUTO)
1503
0
    return 1;
1504
1505
0
  if (read_ahead == DM_READ_AHEAD_NONE)
1506
0
    read_ahead = 0;
1507
1508
0
  if (read_ahead_flags & DM_READ_AHEAD_MINIMUM_FLAG) {
1509
0
    if (!get_dev_node_read_ahead(dev_name, major, minor, &current_read_ahead))
1510
0
      return_0;
1511
1512
0
    if (current_read_ahead >= read_ahead) {
1513
0
      log_debug_activation("%s: retaining kernel read ahead of %" PRIu32
1514
0
          " (requested %" PRIu32 ")",
1515
0
          dev_name, current_read_ahead, read_ahead);
1516
0
      return 1;
1517
0
    }
1518
0
  }
1519
1520
0
  return _set_read_ahead(dev_name, major, minor, read_ahead);
1521
0
}
1522
1523
#else
1524
1525
int get_dev_node_read_ahead(const char *dev_name, uint32_t major, uint32_t minor,
1526
          uint32_t *read_ahead)
1527
{
1528
  *read_ahead = 0;
1529
1530
  return 1;
1531
}
1532
1533
static int _set_dev_node_read_ahead(const char *dev_name,
1534
            uint32_t major, uint32_t minor,
1535
            uint32_t read_ahead, uint32_t read_ahead_flags)
1536
{
1537
  return 1;
1538
}
1539
#endif
1540
1541
typedef enum {
1542
  NODE_ADD,
1543
  NODE_DEL,
1544
  NODE_RENAME,
1545
  NODE_READ_AHEAD,
1546
  NUM_NODES
1547
} node_op_t;
1548
1549
static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major,
1550
           uint32_t minor, uid_t uid, gid_t gid, mode_t mode,
1551
           const char *old_name, uint32_t read_ahead,
1552
           uint32_t read_ahead_flags, int warn_if_udev_failed)
1553
0
{
1554
0
  switch (type) {
1555
0
  case NODE_ADD:
1556
0
    return _add_dev_node(dev_name, major, minor, uid, gid,
1557
0
             mode, warn_if_udev_failed);
1558
0
  case NODE_DEL:
1559
0
    return _rm_dev_node(dev_name, warn_if_udev_failed);
1560
0
  case NODE_RENAME:
1561
0
    return _rename_dev_node(old_name, dev_name, warn_if_udev_failed);
1562
0
  case NODE_READ_AHEAD:
1563
0
    return _set_dev_node_read_ahead(dev_name, major, minor,
1564
0
            read_ahead, read_ahead_flags);
1565
0
  default:
1566
0
    ; /* NOTREACHED */
1567
0
  }
1568
1569
0
  return 1;
1570
0
}
1571
1572
struct dm_thread_state {
1573
  struct dm_list node_ops;
1574
  int count_node_ops[NUM_NODES];
1575
  char uuid_prefix[DM_MAX_UUID_PREFIX_LEN + 1];
1576
  int uuid_prefix_set;
1577
#ifdef UDEV_SYNC_SUPPORT
1578
  int sync_with_udev;
1579
  int udev_checking;
1580
#endif
1581
};
1582
1583
static pthread_key_t _thread_state_key;
1584
static pthread_once_t _thread_state_once = PTHREAD_ONCE_INIT;
1585
1586
static void _pop_node_ops(void);
1587
1588
static void _destroy_thread_state(void *ptr)
1589
0
{
1590
0
  struct dm_thread_state *ts = ptr;
1591
1592
  /*
1593
   * Flush any pending node ops as a safety net in case the
1594
   * caller did not call update_devs() before thread exit.
1595
   * Re-associate so _pop_node_ops() finds the state via accessor.
1596
   */
1597
0
  pthread_setspecific(_thread_state_key, ts);
1598
0
  _pop_node_ops();
1599
0
  pthread_setspecific(_thread_state_key, NULL);
1600
0
  dm_free(ts);
1601
0
}
1602
1603
static void _init_thread_state_key(void)
1604
1
{
1605
  /* pthread_once prevents retry on failure -- nothing we can do */
1606
1
  if (pthread_key_create(&_thread_state_key, _destroy_thread_state))
1607
1
    log_error("Failed to create thread state key.");
1608
1
}
1609
1610
static struct dm_thread_state *_get_thread_state(void)
1611
5.30k
{
1612
5.30k
  struct dm_thread_state *ts;
1613
1614
5.30k
  pthread_once(&_thread_state_once, _init_thread_state_key);
1615
1616
5.30k
  ts = pthread_getspecific(_thread_state_key);
1617
5.30k
  if (!ts) {
1618
1
    if (!(ts = dm_zalloc(sizeof(*ts)))) {
1619
0
      log_error("Failed to allocate thread state.");
1620
0
      return NULL;
1621
0
    }
1622
1
    dm_list_init(&ts->node_ops);
1623
#ifdef UDEV_SYNC_SUPPORT
1624
    ts->sync_with_udev = 1;
1625
    ts->udev_checking = 1;
1626
#endif
1627
1
    pthread_setspecific(_thread_state_key, ts);
1628
1
  }
1629
1630
5.30k
  return ts;
1631
5.30k
}
1632
1633
void dm_thread_state_exit(void)
1634
0
{
1635
0
  struct dm_thread_state *ts = _get_thread_state();
1636
1637
0
  if (ts)
1638
0
    _destroy_thread_state(ts);
1639
1640
0
  pthread_key_delete(_thread_state_key);
1641
0
}
1642
1643
static struct dm_list *_get_node_ops_list(void)
1644
5.30k
{
1645
5.30k
  struct dm_thread_state *ts = _get_thread_state();
1646
1647
5.30k
  return ts ? &ts->node_ops : NULL;
1648
5.30k
}
1649
1650
static int *_get_count_node_ops(void)
1651
0
{
1652
0
  struct dm_thread_state *ts = _get_thread_state();
1653
1654
0
  return ts ? ts->count_node_ops : NULL;
1655
0
}
1656
1657
struct node_op_parms {
1658
  struct dm_list list;
1659
  node_op_t type;
1660
  char *dev_name;
1661
  uint32_t major;
1662
  uint32_t minor;
1663
  uid_t uid;
1664
  gid_t gid;
1665
  mode_t mode;
1666
  uint32_t read_ahead;
1667
  uint32_t read_ahead_flags;
1668
  char *old_name;
1669
  int warn_if_udev_failed;
1670
  unsigned rely_on_udev;
1671
  char names[0];
1672
};
1673
1674
static void _store_str(char **pos, char **ptr, const char *str)
1675
0
{
1676
0
  size_t len = strlen(str) + 1;
1677
0
  memcpy(*pos, str, len);
1678
0
  *ptr = *pos;
1679
0
  *pos += len;
1680
0
}
1681
1682
static void _del_node_op(struct node_op_parms *nop)
1683
0
{
1684
0
  int *count = _get_count_node_ops();
1685
1686
0
  if (count)
1687
0
    count[nop->type]--;
1688
0
  dm_list_del(&nop->list);
1689
0
  dm_free(nop);
1690
0
}
1691
1692
/* Check if there is other the type of node operation stacked */
1693
static int _other_node_ops(node_op_t type)
1694
0
{
1695
0
  int *count = _get_count_node_ops();
1696
0
  unsigned i;
1697
1698
0
  if (!count)
1699
0
    return 0;
1700
1701
0
  for (i = 0; i < NUM_NODES; i++)
1702
0
    if (type != i && count[i])
1703
0
      return 1;
1704
0
  return 0;
1705
0
}
1706
1707
static void _log_node_op(const char *action_str, struct node_op_parms *nop)
1708
0
{
1709
0
  const char *rely = nop->rely_on_udev ? " [trust_udev]" : "" ;
1710
0
  const char *verify = nop->warn_if_udev_failed ? " [verify_udev]" : "";
1711
1712
0
  switch (nop->type) {
1713
0
  case NODE_ADD:
1714
0
    log_debug_activation("%s: %s NODE_ADD (%" PRIu32 ",%" PRIu32 ") %u:%u 0%o%s%s",
1715
0
             nop->dev_name, action_str, nop->major, nop->minor, nop->uid, nop->gid, nop->mode,
1716
0
             rely, verify);
1717
0
    break;
1718
0
  case NODE_DEL:
1719
0
    log_debug_activation("%s: %s NODE_DEL%s%s", nop->dev_name, action_str, rely, verify);
1720
0
    break;
1721
0
  case NODE_RENAME:
1722
0
    log_debug_activation("%s: %s NODE_RENAME to %s%s%s", nop->old_name, action_str, nop->dev_name, rely, verify);
1723
0
    break;
1724
0
  case NODE_READ_AHEAD:
1725
0
    log_debug_activation("%s: %s NODE_READ_AHEAD %" PRIu32 " (flags=%" PRIu32 ")%s%s",
1726
0
             nop->dev_name, action_str, nop->read_ahead, nop->read_ahead_flags, rely, verify);
1727
0
    break;
1728
0
  default:
1729
0
    ; /* NOTREACHED */
1730
0
  }
1731
0
}
1732
1733
static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
1734
        uint32_t minor, uid_t uid, gid_t gid, mode_t mode,
1735
        const char *old_name, uint32_t read_ahead,
1736
        uint32_t read_ahead_flags, int warn_if_udev_failed,
1737
        unsigned rely_on_udev)
1738
0
{
1739
0
  struct node_op_parms *nop;
1740
0
  struct dm_list *noph, *nopht;
1741
0
  struct dm_list *node_ops;
1742
0
  int *count;
1743
0
  size_t len = strlen(dev_name) + strlen(old_name) + 2;
1744
0
  char *pos;
1745
1746
0
  if (!(node_ops = _get_node_ops_list()))
1747
0
    return 0;
1748
1749
0
  if (!(count = _get_count_node_ops()))
1750
0
    return 0;
1751
1752
  /*
1753
   * Note: warn_if_udev_failed must have valid content
1754
   */
1755
0
  if ((type == NODE_DEL) && _other_node_ops(type))
1756
    /*
1757
     * Ignore any outstanding operations on the node if deleting it.
1758
     */
1759
0
    dm_list_iterate_safe(noph, nopht, node_ops) {
1760
0
      nop = dm_list_item(noph, struct node_op_parms);
1761
0
      if (!strcmp(dev_name, nop->dev_name)) {
1762
0
        _log_node_op("Unstacking", nop);
1763
0
        _del_node_op(nop);
1764
0
        if (!_other_node_ops(type))
1765
0
          break; /* no other non DEL ops */
1766
0
      }
1767
0
    }
1768
0
  else if ((type == NODE_ADD) && count[NODE_DEL])
1769
    /*
1770
     * Ignore previous DEL operation on added node.
1771
     * (No other operations for this device than DEL could be stacked here).
1772
     */
1773
0
    dm_list_iterate_safe(noph, nopht, node_ops) {
1774
0
      nop = dm_list_item(noph, struct node_op_parms);
1775
0
      if ((nop->type == NODE_DEL) &&
1776
0
          !strcmp(dev_name, nop->dev_name)) {
1777
0
        _log_node_op("Unstacking", nop);
1778
0
        _del_node_op(nop);
1779
0
        break; /* no other DEL ops */
1780
0
      }
1781
0
    }
1782
0
  else if (type == NODE_RENAME)
1783
    /*
1784
     * Ignore any outstanding operations if renaming it.
1785
     *
1786
     * Currently  RENAME operation happens through 'suspend -> resume'.
1787
     * On 'resume' device is added with read_ahead settings, so it is
1788
     * safe to remove any stacked ADD, RENAME, READ_AHEAD operation
1789
     * There cannot be any DEL operation on the renamed device.
1790
     */
1791
0
    dm_list_iterate_safe(noph, nopht, node_ops) {
1792
0
      nop = dm_list_item(noph, struct node_op_parms);
1793
0
      if (!strcmp(old_name, nop->dev_name)) {
1794
0
        _log_node_op("Unstacking", nop);
1795
0
        _del_node_op(nop);
1796
0
      }
1797
0
    }
1798
0
  else if (type == NODE_READ_AHEAD) {
1799
    /* udev doesn't process readahead */
1800
0
    rely_on_udev = 0;
1801
0
    warn_if_udev_failed = 0;
1802
0
  }
1803
1804
0
  if (!(nop = dm_malloc(sizeof(*nop) + len))) {
1805
0
    log_error("Insufficient memory to stack mknod operation");
1806
0
    return 0;
1807
0
  }
1808
1809
0
  pos = nop->names;
1810
0
  nop->type = type;
1811
0
  nop->major = major;
1812
0
  nop->minor = minor;
1813
0
  nop->uid = uid;
1814
0
  nop->gid = gid;
1815
0
  nop->mode = mode;
1816
0
  nop->read_ahead = read_ahead;
1817
0
  nop->read_ahead_flags = read_ahead_flags;
1818
0
  nop->rely_on_udev = rely_on_udev;
1819
1820
  /*
1821
   * Clear warn_if_udev_failed if rely_on_udev is set.  It doesn't get
1822
   * checked in this case - this just removes the flag from log messages.
1823
   */
1824
0
  nop->warn_if_udev_failed = rely_on_udev ? 0 : warn_if_udev_failed;
1825
1826
0
  _store_str(&pos, &nop->dev_name, dev_name);
1827
0
  _store_str(&pos, &nop->old_name, old_name);
1828
1829
0
  count[type]++;
1830
0
  dm_list_add(node_ops, &nop->list);
1831
1832
0
  _log_node_op("Stacking", nop);
1833
1834
0
  return 1;
1835
0
}
1836
1837
static void _pop_node_ops(void)
1838
5.30k
{
1839
5.30k
  struct dm_list *noph, *nopht, *node_ops;
1840
5.30k
  struct node_op_parms *nop;
1841
1842
5.30k
  if (!(node_ops = _get_node_ops_list()))
1843
0
    return;
1844
1845
5.30k
  dm_list_iterate_safe(noph, nopht, node_ops) {
1846
0
    nop = dm_list_item(noph, struct node_op_parms);
1847
0
    if (!nop->rely_on_udev) {
1848
0
      _log_node_op("Processing", nop);
1849
0
      _do_node_op(nop->type, nop->dev_name, nop->major, nop->minor,
1850
0
            nop->uid, nop->gid, nop->mode, nop->old_name,
1851
0
            nop->read_ahead, nop->read_ahead_flags,
1852
0
            nop->warn_if_udev_failed);
1853
0
    } else
1854
0
      _log_node_op("Skipping", nop);
1855
0
    _del_node_op(nop);
1856
0
  }
1857
5.30k
}
1858
1859
int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
1860
     uid_t uid, gid_t gid, mode_t mode, int check_udev, unsigned rely_on_udev)
1861
0
{
1862
0
  return _stack_node_op(NODE_ADD, dev_name, major, minor, uid,
1863
0
            gid, mode, "", 0, 0, check_udev, rely_on_udev);
1864
0
}
1865
1866
int rename_dev_node(const char *old_name, const char *new_name, int check_udev, unsigned rely_on_udev)
1867
0
{
1868
0
  return _stack_node_op(NODE_RENAME, new_name, 0, 0, 0,
1869
0
            0, 0, old_name, 0, 0, check_udev, rely_on_udev);
1870
0
}
1871
1872
int rm_dev_node(const char *dev_name, int check_udev, unsigned rely_on_udev)
1873
0
{
1874
0
  return _stack_node_op(NODE_DEL, dev_name, 0, 0, 0,
1875
0
            0, 0, "", 0, 0, check_udev, rely_on_udev);
1876
0
}
1877
1878
int set_dev_node_read_ahead(const char *dev_name,
1879
                            uint32_t major, uint32_t minor,
1880
          uint32_t read_ahead, uint32_t read_ahead_flags)
1881
0
{
1882
0
  if (read_ahead == DM_READ_AHEAD_AUTO)
1883
0
    return 1;
1884
1885
0
  return _stack_node_op(NODE_READ_AHEAD, dev_name, major, minor, 0, 0,
1886
0
                              0, "", read_ahead, read_ahead_flags, 0, 0);
1887
0
}
1888
1889
void update_devs(void)
1890
5.30k
{
1891
5.30k
  _pop_node_ops();
1892
5.30k
}
1893
1894
static int _canonicalize_and_set_dir(const char *src, const char *suffix, size_t max_len, char *dir)
1895
0
{
1896
0
  size_t len;
1897
0
  const char *slash;
1898
1899
0
  if (*src != '/') {
1900
0
    log_debug_activation("Invalid directory value, %s: "
1901
0
             "not an absolute name.", src);
1902
0
    return 0;
1903
0
  }
1904
1905
0
  len = strlen(src);
1906
0
  slash = src[len-1] == '/' ? "" : "/";
1907
1908
0
  if (dm_snprintf(dir, max_len, "%s%s%s", src, slash, suffix ? suffix : "") < 0) {
1909
0
    log_debug_activation("Invalid directory value, %s: name too long.", src);
1910
0
    return 0;
1911
0
  }
1912
1913
0
  return 1;
1914
0
}
1915
1916
int dm_set_dev_dir(const char *dev_dir)
1917
0
{
1918
0
  char new_dir[PATH_MAX];
1919
1920
0
  if (!_canonicalize_and_set_dir(dev_dir, DM_DIR, sizeof new_dir, new_dir))
1921
0
    return_0;
1922
1923
0
  if (!strcmp(new_dir, _dm_dir))
1924
0
    return 1;
1925
1926
0
  if (!_is_init_thread("change dev dir"))
1927
0
    return 1;
1928
1929
0
  return dm_strncpy(_dm_dir, new_dir, sizeof _dm_dir);
1930
0
}
1931
1932
const char *dm_dir(void)
1933
0
{
1934
0
  return _dm_dir;
1935
0
}
1936
1937
int dm_set_sysfs_dir(const char *sysfs_dir)
1938
0
{
1939
0
  char new_dir[PATH_MAX];
1940
1941
0
  if (!sysfs_dir || !*sysfs_dir)
1942
0
    new_dir[0] = '\0';
1943
0
  else if (!_canonicalize_and_set_dir(sysfs_dir, NULL, sizeof new_dir, new_dir))
1944
0
    return_0;
1945
1946
0
  if (!strcmp(new_dir, _sysfs_dir))
1947
0
    return 1;
1948
1949
0
  if (!_is_init_thread("change sysfs dir"))
1950
0
    return 1;
1951
1952
0
  return dm_strncpy(_sysfs_dir, new_dir, sizeof _sysfs_dir);
1953
0
}
1954
1955
const char *dm_sysfs_dir(void)
1956
0
{
1957
0
  return _sysfs_dir;
1958
0
}
1959
1960
/*
1961
 * Replace existing uuid_prefix provided it isn't too long.
1962
 */
1963
int dm_set_uuid_prefix(const char *uuid_prefix)
1964
0
{
1965
0
  struct dm_thread_state *ts;
1966
0
  size_t len;
1967
1968
0
  if (!uuid_prefix)
1969
0
    return_0;
1970
1971
0
  if ((len = strlen(uuid_prefix)) > DM_MAX_UUID_PREFIX_LEN) {
1972
0
    log_error("New uuid prefix %s too long.", uuid_prefix);
1973
0
    return 0;
1974
0
  }
1975
1976
0
  if (!(ts = _get_thread_state()))
1977
0
    return_0;
1978
1979
0
  memcpy(ts->uuid_prefix, uuid_prefix, len + 1);
1980
0
  ts->uuid_prefix_set = 1;
1981
1982
0
  return 1;
1983
0
}
1984
1985
const char *dm_uuid_prefix(void)
1986
0
{
1987
0
  struct dm_thread_state *ts = _get_thread_state();
1988
1989
0
  if (ts && ts->uuid_prefix_set)
1990
0
    return ts->uuid_prefix;
1991
1992
0
  return _default_uuid_prefix;
1993
0
}
1994
1995
static int _is_octal(int a)
1996
0
{
1997
0
  return (((a) & ~7) == '0');
1998
0
}
1999
2000
/* Convert mangled mountinfo into normal ASCII string */
2001
static void _unmangle_mountinfo_string(const char *src, char *buf)
2002
0
{
2003
0
  while (*src) {
2004
0
    if ((*src == '\\') &&
2005
0
        _is_octal(src[1]) && _is_octal(src[2]) && _is_octal(src[3])) {
2006
0
      *buf++ = 64 * (src[1] & 7) + 8 * (src[2] & 7) + (src[3] & 7);
2007
0
      src += 4;
2008
0
    } else
2009
0
      *buf++ = *src++;
2010
0
  }
2011
0
  *buf = '\0';
2012
0
}
2013
2014
/* coverity[+tainted_string_sanitize_content:arg-0] */
2015
0
static int _sanitize_line(const char *line) { return 1; }
2016
2017
/* Parse one line of mountinfo and unmangled target line */
2018
static int _mountinfo_parse_line(const char *line, unsigned *maj, unsigned *min, char *buf)
2019
0
{
2020
0
  char root[PATH_MAX + 1]; /* sscanf needs extra '\0' */
2021
0
  char target[PATH_MAX + 1];
2022
0
  const char *devmapper;
2023
0
  struct dm_task *dmt;
2024
0
  struct dm_info info;
2025
0
  unsigned i;
2026
2027
  /* TODO: maybe detect availability of  %ms  glib support ? */
2028
0
  if (sscanf(line, "%*u %*u %u:%u %" DM_TO_STRING(PATH_MAX)
2029
0
       "s %" DM_TO_STRING(PATH_MAX) "s",
2030
0
       maj, min, root, target) < 4) {
2031
0
    log_error("Failed to parse mountinfo line.");
2032
0
    return 0;
2033
0
  }
2034
2035
  /* btrfs fakes device numbers, but there is still /dev/mapper name
2036
   * placed in mountinfo, so try to detect proper major:minor via this */
2037
0
  if (*maj == 0 && (devmapper = strstr(line, "/dev/mapper/"))) {
2038
0
    if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
2039
0
      log_error("Mount info task creation failed.");
2040
0
      return 0;
2041
0
    }
2042
0
    devmapper += 12; /* skip fixed prefix */
2043
0
    for (i = 0; devmapper[i] && devmapper[i] != ' ' && i < sizeof(root)-1; ++i)
2044
0
      root[i] = devmapper[i];
2045
0
    root[i] = 0;
2046
0
    _unmangle_mountinfo_string(root, buf);
2047
0
    buf[DM_NAME_LEN] = 0; /* cut away */
2048
2049
0
    if (dm_task_set_name(dmt, buf) &&
2050
0
        dm_task_no_open_count(dmt) &&
2051
0
        dm_task_run(dmt) &&
2052
0
        dm_task_get_info(dmt, &info)) {
2053
0
      log_debug("Replacing mountinfo device (%u:%u) with matching DM device %s (%u:%u).",
2054
0
          *maj, *min, buf, info.major, info.minor);
2055
0
      *maj = info.major;
2056
0
      *min = info.minor;
2057
0
    }
2058
0
    dm_task_destroy(dmt);
2059
0
  }
2060
2061
0
  _unmangle_mountinfo_string(target, buf);
2062
2063
0
  return 1;
2064
0
}
2065
2066
/*
2067
 * Function to operate on individual mountinfo line,
2068
 * minor, major and mount target are parsed and unmangled
2069
 */
2070
int dm_mountinfo_read(dm_mountinfo_line_callback_fn read_fn, void *cb_data)
2071
0
{
2072
0
  FILE *minfo;
2073
0
  char buffer[2 * PATH_MAX];
2074
0
  char target[PATH_MAX];
2075
0
  unsigned maj, min;
2076
0
  int r = 1;
2077
2078
0
  if (!(minfo = fopen(_mountinfo, "r"))) {
2079
0
    if (errno != ENOENT)
2080
0
      log_sys_error("fopen", _mountinfo);
2081
0
    else
2082
0
      log_sys_debug("fopen", _mountinfo);
2083
0
    return 0;
2084
0
  }
2085
2086
0
  while (!feof(minfo) && fgets(buffer, sizeof(buffer), minfo))
2087
0
    if (!_sanitize_line(buffer) ||
2088
0
        !_mountinfo_parse_line(buffer, &maj, &min, target) ||
2089
0
        !read_fn(buffer, maj, min, target, cb_data)) {
2090
0
      stack;
2091
0
      r = 0;
2092
0
      break;
2093
0
    }
2094
2095
0
  if (fclose(minfo))
2096
0
    log_sys_error("fclose", _mountinfo);
2097
2098
0
  return r;
2099
0
}
2100
2101
static int _sysfs_get_dm_name(uint32_t major, uint32_t minor, char *buf, size_t buf_size)
2102
0
{
2103
0
  char sysfs_path[PATH_MAX], temp_buf[2 * DM_NAME_LEN];
2104
0
  FILE *fp = NULL;
2105
0
  int r = 0;
2106
0
  size_t len;
2107
2108
0
  if (dm_snprintf(sysfs_path, sizeof(sysfs_path),
2109
0
      "%sdev/block/%" PRIu32 ":%" PRIu32
2110
0
      "/dm/name", _sysfs_dir, major, minor) < 0) {
2111
0
    log_error("_sysfs_get_dm_name: dm_snprintf failed.");
2112
0
    goto bad;
2113
0
  }
2114
2115
0
  if (!(fp = fopen(sysfs_path, "r"))) {
2116
0
    if (errno == ENOENT)
2117
0
      log_sys_debug("fopen", sysfs_path);
2118
0
    else
2119
0
      log_sys_error("fopen", sysfs_path);
2120
0
    goto bad;
2121
0
  }
2122
2123
0
  if (!fgets(temp_buf, sizeof(temp_buf), fp)) {
2124
0
    log_sys_error("fgets", sysfs_path);
2125
0
    goto bad;
2126
0
  }
2127
2128
0
  len = strlen(temp_buf);
2129
2130
0
  if (len > buf_size) {
2131
0
    log_error("_sysfs_get_dm_name: supplied buffer too small.");
2132
0
    goto bad;
2133
0
  }
2134
2135
0
  if (len)
2136
0
    --len;  /* strip \n */
2137
2138
0
  memcpy(buf, temp_buf, len);
2139
0
  buf[len] = '\0';
2140
2141
0
  r = 1;
2142
0
bad:
2143
0
  if (fp && fclose(fp))
2144
0
    log_sys_error("fclose", sysfs_path);
2145
2146
0
  return r;
2147
0
}
2148
2149
static int _sysfs_get_dev_major_minor(const char *path, uint32_t major, uint32_t minor)
2150
0
{
2151
0
  FILE *fp;
2152
0
  uint32_t ma, mi;
2153
0
  int r;
2154
2155
0
  if (!(fp = fopen(path, "r")))
2156
0
    return 0;
2157
2158
0
  r = (fscanf(fp, "%" PRIu32 ":%" PRIu32 , &ma, &mi) == 2) &&
2159
0
    (ma == major) && (mi == minor);
2160
  // log_debug("Checking %s  %u:%u  -> %d", path, ma, mi, r);
2161
2162
0
  if (fclose(fp))
2163
0
    log_sys_error("fclose", path);
2164
2165
0
  return r;
2166
0
}
2167
2168
static int _sysfs_find_kernel_name(uint32_t major, uint32_t minor, char *buf, size_t buf_size)
2169
0
{
2170
  /* sorted alphabetically */
2171
0
  static const char _ignore_sysfs[][16] = {
2172
0
    ".",
2173
0
    "..",
2174
0
    "bdi",
2175
0
    "dev",
2176
0
    "device",
2177
0
    "holders",
2178
0
    "integrity",
2179
0
    "loop",
2180
0
    "md",
2181
0
    "mq",
2182
0
    "power",
2183
0
    "queue",
2184
0
    "removable",
2185
0
    "slave",
2186
0
    "slaves",
2187
0
    "subsystem",
2188
0
    "trace",
2189
0
    "uevent"
2190
0
  };
2191
0
  const char *name, *name_dev;
2192
0
  char path[PATH_MAX];
2193
0
  struct dirent *dirent, *dirent_dev;
2194
0
  DIR *d, *d_dev;
2195
0
  int r = 0, sz;
2196
2197
0
  if (!*_sysfs_dir ||
2198
0
      dm_snprintf(path, sizeof(path), "%sblock/", _sysfs_dir) < 0) {
2199
0
    log_error("Failed to build sysfs_path.");
2200
0
    return 0;
2201
0
  }
2202
2203
0
  if (!(d = opendir(path))) {
2204
0
    log_sys_error("opendir", path);
2205
0
    return 0;
2206
0
  }
2207
2208
0
  while (!r && (dirent = readdir(d))) {
2209
0
    name = dirent->d_name;
2210
2211
0
    if (!strcmp(name, ".") || !strcmp(name, ".."))
2212
0
      continue;
2213
2214
0
    if ((sz = dm_snprintf(path, sizeof(path), "%sblock/%s/dev",
2215
0
              _sysfs_dir, name)) < 5) {
2216
0
      log_warn("Couldn't create path for %s.", name);
2217
0
      continue;
2218
0
    }
2219
2220
0
    if (_sysfs_get_dev_major_minor(path, major, minor)) {
2221
0
      r = dm_strncpy(buf, name, buf_size);
2222
0
      break; /* found */
2223
0
    }
2224
2225
0
    path[sz - 4] = 0; /* strip /dev from end of path string */
2226
2227
    /* let's assume there is no tree-complex device in past systems */
2228
0
    if (!(d_dev = opendir(path))) {
2229
      /* Silently skip non-directories, log other errors */
2230
0
      if (errno != ENOTDIR)
2231
0
        log_sys_debug("opendir", path);
2232
0
      continue;
2233
0
    }
2234
2235
0
    while ((dirent_dev = readdir(d_dev))) {
2236
0
      name_dev = dirent_dev->d_name;
2237
2238
      /* skip known ignorable paths using binary search */
2239
0
      if (bsearch(name_dev, _ignore_sysfs, DM_ARRAY_SIZE(_ignore_sysfs),
2240
0
            sizeof(_ignore_sysfs[0]), (int (*)(const void *, const void *))strcmp))
2241
0
        continue;
2242
2243
0
      if (dm_snprintf(path, sizeof(path), "%sblock/%s/%s/dev",
2244
0
          _sysfs_dir, name, name_dev) == -1) {
2245
0
        log_warn("Couldn't create path for %s/%s.", name, name_dev);
2246
0
        continue;
2247
0
      }
2248
2249
0
      if (_sysfs_get_dev_major_minor(path, major, minor)) {
2250
0
        r = dm_strncpy(buf, name_dev, buf_size);
2251
0
        break; /* found */
2252
0
      }
2253
0
    }
2254
2255
0
    if (closedir(d_dev))
2256
0
      log_sys_debug("closedir", name);
2257
0
    }
2258
2259
0
  if (closedir(d))
2260
0
    log_sys_debug("closedir", path);
2261
2262
0
  return r;
2263
0
}
2264
2265
static int _sysfs_get_kernel_name(uint32_t major, uint32_t minor, char *buf, size_t buf_size)
2266
0
{
2267
0
  char *name, *sysfs_path, *temp_buf = NULL;
2268
0
  ssize_t size;
2269
0
  int r = 0;
2270
2271
0
  if (!(sysfs_path = malloc(PATH_MAX)) ||
2272
0
      !(temp_buf = malloc(PATH_MAX))) {
2273
0
    log_error("_sysfs_get_kernel_name: failed to allocate temporary buffers");
2274
0
    goto bad;
2275
0
  }
2276
2277
0
  if (dm_snprintf(sysfs_path, PATH_MAX, "%sdev/block/%" PRIu32 ":%" PRIu32,
2278
0
      _sysfs_dir, major, minor) < 0) {
2279
0
    log_error("_sysfs_get_kernel_name: dm_snprintf failed");
2280
0
    goto bad;
2281
0
  }
2282
2283
0
  if ((size = readlink(sysfs_path, temp_buf, PATH_MAX - 1)) < 0) {
2284
0
    if (errno != ENOENT)
2285
0
      log_sys_error("readlink", sysfs_path);
2286
0
    else {
2287
0
      log_sys_debug("readlink", sysfs_path);
2288
0
      r = _sysfs_find_kernel_name(major, minor, buf, buf_size);
2289
0
      goto out;
2290
0
    }
2291
0
    goto bad;
2292
0
  }
2293
0
  temp_buf[size] = '\0';
2294
2295
0
  if (!(name = strrchr(temp_buf, '/'))) {
2296
0
    log_error("Could not locate device kernel name in sysfs path %s", temp_buf);
2297
0
    goto bad;
2298
0
  }
2299
0
  name += 1;
2300
0
  if (!_dm_strncpy(buf, name, buf_size)) {
2301
0
    log_error("_sysfs_get_kernel_name: output buffer too small");
2302
0
    goto bad;
2303
0
  }
2304
0
  r = 1;
2305
0
bad:
2306
0
out:
2307
0
  free(temp_buf);
2308
0
  free(sysfs_path);
2309
2310
0
  return r;
2311
0
}
2312
2313
int dm_device_get_name(uint32_t major, uint32_t minor, int prefer_kernel_name,
2314
           char *buf, size_t buf_size)
2315
0
{
2316
0
  if (!*_sysfs_dir)
2317
0
    return 0;
2318
2319
  /*
2320
   * device-mapper devices and prefer_kernel_name = 0
2321
   * get dm name by reading /sys/dev/block/major:minor/dm/name,
2322
   * fallback to _sysfs_get_kernel_name if not successful
2323
   */
2324
0
  if (dm_is_dm_major(major) && !prefer_kernel_name) {
2325
0
    if (_sysfs_get_dm_name(major, minor, buf, buf_size))
2326
0
      return 1;
2327
0
    else
2328
0
      stack;
2329
0
  }
2330
2331
  /*
2332
   * non-device-mapper devices or prefer_kernel_name = 1
2333
   * get kernel name using readlink /sys/dev/block/major:minor -> .../dm-X
2334
   */
2335
0
  return _sysfs_get_kernel_name(major, minor, buf, buf_size);
2336
0
}
2337
2338
int dm_device_has_holders(uint32_t major, uint32_t minor)
2339
0
{
2340
0
  char sysfs_path[PATH_MAX];
2341
0
  struct stat st;
2342
2343
0
  if (!*_sysfs_dir)
2344
0
    return 0;
2345
2346
0
  if (dm_snprintf(sysfs_path, PATH_MAX, "%sdev/block/%" PRIu32
2347
0
      ":%" PRIu32 "/holders", _sysfs_dir, major, minor) < 0) {
2348
0
    log_warn("WARNING: sysfs_path dm_snprintf failed.");
2349
0
    return 0;
2350
0
  }
2351
2352
0
  if (stat(sysfs_path, &st)) {
2353
0
    if (errno != ENOENT)
2354
0
      log_sys_debug("stat", sysfs_path);
2355
0
    return 0;
2356
0
  }
2357
2358
0
  return !dm_is_empty_dir(sysfs_path);
2359
0
}
2360
2361
static int _mounted_fs_on_device(const char *kernel_dev_name)
2362
0
{
2363
0
  char sysfs_path[PATH_MAX];
2364
0
  struct dirent *dirent;
2365
0
  DIR *d;
2366
0
  struct stat st;
2367
0
  int r = 0;
2368
2369
0
  if (dm_snprintf(sysfs_path, PATH_MAX, "%sfs", _sysfs_dir) < 0) {
2370
0
    log_warn("WARNING: sysfs_path dm_snprintf failed.");
2371
0
    return 0;
2372
0
  }
2373
2374
0
  if (!(d = opendir(sysfs_path))) {
2375
0
    if (errno != ENOENT)
2376
0
      log_sys_debug("opendir", sysfs_path);
2377
0
    return 0;
2378
0
  }
2379
2380
0
  while ((dirent = readdir(d))) {
2381
0
    if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
2382
0
      continue;
2383
2384
0
    if (dm_snprintf(sysfs_path, PATH_MAX, "%sfs/%s/%s",
2385
0
        _sysfs_dir, dirent->d_name, kernel_dev_name) < 0) {
2386
0
      log_warn("WARNING: sysfs_path dm_snprintf failed.");
2387
0
      break;
2388
0
    }
2389
2390
0
    if (!stat(sysfs_path, &st)) {
2391
      /* found! */
2392
0
      r = 1;
2393
0
      break;
2394
0
    }
2395
0
    else if (errno != ENOENT) {
2396
0
      log_sys_debug("stat", sysfs_path);
2397
0
      break;
2398
0
    }
2399
0
  }
2400
2401
0
  if (closedir(d))
2402
0
    log_sys_debug("closedir", kernel_dev_name);
2403
2404
0
  return r;
2405
0
}
2406
2407
struct mountinfo_s {
2408
  unsigned maj;
2409
  unsigned min;
2410
  int mounted;
2411
};
2412
2413
static int _device_has_mounted_fs(char *buffer, unsigned major, unsigned minor,
2414
          char *target, void *cb_data)
2415
0
{
2416
0
  struct mountinfo_s *data = cb_data;
2417
0
  char kernel_dev_name[PATH_MAX];
2418
2419
0
  if ((major == data->maj) && (minor == data->min)) {
2420
0
    if (!dm_device_get_name(major, minor, 1, kernel_dev_name,
2421
0
          sizeof(kernel_dev_name))) {
2422
0
      stack;
2423
0
      *kernel_dev_name = '\0';
2424
0
    }
2425
0
    log_verbose("Device %s (%u:%u) appears to be mounted on %s.",
2426
0
          kernel_dev_name, major, minor, target);
2427
0
    data->mounted = 1;
2428
0
  }
2429
2430
0
  return 1;
2431
0
}
2432
2433
int dm_device_has_mounted_fs(uint32_t major, uint32_t minor)
2434
0
{
2435
0
  char kernel_dev_name[PATH_MAX];
2436
0
  struct mountinfo_s data = {
2437
0
    .maj = major,
2438
0
    .min = minor,
2439
0
  };
2440
2441
0
  if (!dm_mountinfo_read(_device_has_mounted_fs, &data))
2442
0
    stack;
2443
2444
0
  if (data.mounted)
2445
0
    return 1;
2446
  /*
2447
   * TODO: Verify dm_mountinfo_read() is superset
2448
   * and remove sysfs check (namespaces)
2449
   */
2450
  /* Get kernel device name first */
2451
0
  if (!dm_device_get_name(major, minor, 1, kernel_dev_name, PATH_MAX))
2452
0
    return 0;
2453
2454
  /* Check /sys/fs/<fs_name>/<kernel_dev_name> presence */
2455
0
  return _mounted_fs_on_device(kernel_dev_name);
2456
0
}
2457
2458
int dm_mknodes(const char *name)
2459
0
{
2460
0
  struct dm_task *dmt;
2461
0
  int r = 0;
2462
2463
0
  if (!(dmt = dm_task_create(DM_DEVICE_MKNODES)))
2464
0
    return_0;
2465
2466
0
  if (name && !dm_task_set_name(dmt, name))
2467
0
    goto out;
2468
2469
0
  if (!dm_task_no_open_count(dmt))
2470
0
    goto out;
2471
2472
0
  r = dm_task_run(dmt);
2473
2474
0
out:
2475
0
  dm_task_destroy(dmt);
2476
0
  return r;
2477
0
}
2478
2479
int dm_driver_version(char *version, size_t size)
2480
0
{
2481
0
  struct dm_task *dmt;
2482
0
  int r = 0;
2483
2484
0
  if (!(dmt = dm_task_create(DM_DEVICE_VERSION)))
2485
0
    return_0;
2486
2487
0
  if (!dm_task_run(dmt)) {
2488
0
    log_error("Failed to get driver version.");
2489
0
    goto out;
2490
0
  }
2491
2492
0
  if (!dm_task_get_driver_version(dmt, version, size))
2493
0
    goto out;
2494
2495
0
  r = 1;
2496
2497
0
out:
2498
0
  dm_task_destroy(dmt);
2499
0
  return r;
2500
0
}
2501
2502
static void _set_cookie_flags(struct dm_task *dmt, uint16_t flags)
2503
0
{
2504
0
  if (!dm_cookie_supported())
2505
0
    return;
2506
2507
0
  if (_udev_disabled) {
2508
    /*
2509
     * If udev is disabled, hardcode this functionality:
2510
     *   - we want libdm to create the nodes
2511
     *   - we don't want the /dev/mapper and any subsystem
2512
     *     related content to be created by udev if udev
2513
     *     rules are installed
2514
     */
2515
0
    flags &= ~DM_UDEV_DISABLE_LIBRARY_FALLBACK;
2516
0
    flags |= DM_UDEV_DISABLE_DM_RULES_FLAG | DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
2517
0
  }
2518
2519
0
  dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT;
2520
0
}
2521
2522
#ifndef UDEV_SYNC_SUPPORT
2523
void dm_udev_set_sync_support(int sync_with_udev)
2524
0
{
2525
0
}
2526
2527
int dm_udev_get_sync_support(void)
2528
0
{
2529
0
  return 0;
2530
0
}
2531
2532
void dm_udev_set_checking(int checking)
2533
0
{
2534
0
}
2535
2536
int dm_udev_get_checking(void)
2537
0
{
2538
0
  return 0;
2539
0
}
2540
2541
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)
2542
0
{
2543
0
  _set_cookie_flags(dmt, flags);
2544
2545
0
  *cookie = 0;
2546
0
  dmt->cookie_set = 1;
2547
2548
0
  return 1;
2549
0
}
2550
2551
int dm_udev_create_cookie(uint32_t *cookie)
2552
0
{
2553
0
  *cookie = 0;
2554
2555
0
  return 1;
2556
0
}
2557
2558
int dm_udev_complete(uint32_t cookie)
2559
0
{
2560
0
  return 1;
2561
0
}
2562
2563
int dm_udev_wait(uint32_t cookie)
2564
0
{
2565
0
  update_devs();
2566
2567
0
  return 1;
2568
0
}
2569
2570
int dm_udev_wait_immediate(uint32_t cookie, int *ready)
2571
0
{
2572
0
  update_devs();
2573
0
  *ready = 1;
2574
2575
0
  return 1;
2576
0
}
2577
2578
#else   /* UDEV_SYNC_SUPPORT */
2579
2580
static int _check_semaphore_is_supported(void)
2581
{
2582
  int maxid;
2583
  union semun arg;
2584
  struct seminfo seminfo;
2585
2586
  arg.__buf = &seminfo;
2587
  maxid = semctl(0, 0, SEM_INFO, arg);
2588
2589
  if (maxid < 0) {
2590
    log_warn("Kernel not configured for semaphores (System V IPC). "
2591
       "Not using udev synchronization code.");
2592
    return 0;
2593
  }
2594
2595
  return 1;
2596
}
2597
2598
static int _check_udev_is_running(void)
2599
{
2600
  struct udev *udev;
2601
  struct udev_queue *udev_queue;
2602
  int r;
2603
2604
  if (!(udev = udev_new()))
2605
    goto_bad;
2606
2607
  if (!(udev_queue = udev_queue_new(udev))) {
2608
    udev_unref(udev);
2609
    goto_bad;
2610
  }
2611
2612
  if (!(r = udev_queue_get_udev_is_active(udev_queue)))
2613
    log_debug_activation("Udev is not running. "
2614
             "Not using udev synchronization code.");
2615
2616
  udev_queue_unref(udev_queue);
2617
  udev_unref(udev);
2618
2619
  return r;
2620
2621
bad:
2622
  log_error("Could not get udev state. Assuming udev is not running.");
2623
  return 0;
2624
}
2625
2626
static pthread_once_t _udev_sync_once = PTHREAD_ONCE_INIT;
2627
2628
static void _init_udev_sync_requirements(void)
2629
{
2630
  _semaphore_supported = _check_semaphore_is_supported();
2631
  _udev_running = _check_udev_is_running();
2632
2633
  if (_udev_disabled && _udev_running)
2634
    log_warn("Udev is running and DM_DISABLE_UDEV environment variable is set. "
2635
       "Bypassing udev, device-mapper library will manage device "
2636
       "nodes in device directory.");
2637
}
2638
2639
void dm_udev_set_sync_support(int sync_with_udev)
2640
{
2641
  struct dm_thread_state *ts;
2642
2643
  pthread_once(&_udev_sync_once, _init_udev_sync_requirements);
2644
2645
  if ((ts = _get_thread_state()))
2646
    ts->sync_with_udev = sync_with_udev;
2647
}
2648
2649
int dm_udev_get_sync_support(void)
2650
{
2651
  struct dm_thread_state *ts;
2652
2653
  pthread_once(&_udev_sync_once, _init_udev_sync_requirements);
2654
2655
  ts = _get_thread_state();
2656
2657
  return !_udev_disabled && _semaphore_supported &&
2658
    dm_cookie_supported() && _udev_running &&
2659
    (ts ? ts->sync_with_udev : 1);
2660
}
2661
2662
void dm_udev_set_checking(int checking)
2663
{
2664
  struct dm_thread_state *ts;
2665
2666
  if ((ts = _get_thread_state()))
2667
    ts->udev_checking = checking;
2668
2669
  if (checking)
2670
    log_debug_activation("DM udev checking enabled");
2671
  else
2672
    log_debug_activation("DM udev checking disabled");
2673
}
2674
2675
int dm_udev_get_checking(void)
2676
{
2677
  struct dm_thread_state *ts = _get_thread_state();
2678
2679
  return ts ? ts->udev_checking : 1;
2680
}
2681
2682
static int _get_cookie_sem(uint32_t cookie, int *semid)
2683
{
2684
  if (cookie >> 16 != DM_COOKIE_MAGIC) {
2685
    log_error("Could not continue to access notification "
2686
        "semaphore identified by cookie value %"
2687
        PRIu32 " (0x%x). Incorrect cookie prefix.",
2688
        cookie, cookie);
2689
    return 0;
2690
  }
2691
2692
  if ((*semid = semget((key_t) cookie, 1, 0)) >= 0)
2693
    return 1;
2694
2695
  switch (errno) {
2696
    case ENOENT:
2697
      log_error("Could not find notification "
2698
          "semaphore identified by cookie "
2699
          "value %" PRIu32 " (0x%x)",
2700
          cookie, cookie);
2701
      break;
2702
    case EACCES:
2703
      log_error("No permission to access "
2704
          "notification semaphore identified "
2705
          "by cookie value %" PRIu32 " (0x%x)",
2706
          cookie, cookie);
2707
      break;
2708
    default:
2709
      log_error("Failed to access notification "
2710
           "semaphore identified by cookie "
2711
           "value %" PRIu32 " (0x%x): %s",
2712
          cookie, cookie, strerror(errno));
2713
      break;
2714
  }
2715
2716
  return 0;
2717
}
2718
2719
static int _udev_notify_sem_inc(uint32_t cookie, int semid)
2720
{
2721
  struct sembuf sb = {0, 1, 0};
2722
  int val;
2723
2724
  if (semop(semid, &sb, 1) < 0) {
2725
    log_error("cookie inc: semid %d: semop failed for cookie 0x%" PRIx32 ": %s",
2726
        semid, cookie, strerror(errno));
2727
    return 0;
2728
  }
2729
2730
  if ((val = semctl(semid, 0, GETVAL)) < 0) {
2731
    log_warn("cookie inc: semid %d: semctl GETVAL failed for "
2732
        "cookie 0x%" PRIx32 ": %s",
2733
        semid, cookie, strerror(errno));
2734
    log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented.",
2735
              cookie, semid);
2736
  } else
2737
    log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented to %d",
2738
             cookie, semid, val);
2739
2740
  return 1;
2741
}
2742
2743
static int _udev_notify_sem_dec(uint32_t cookie, int semid)
2744
{
2745
  struct sembuf sb = {0, -1, IPC_NOWAIT};
2746
  int val;
2747
2748
  if ((val = semctl(semid, 0, GETVAL)) < 0)
2749
    log_warn("cookie dec: semid %d: semctl GETVAL failed for "
2750
       "cookie 0x%" PRIx32 ": %s",
2751
       semid, cookie, strerror(errno));
2752
2753
  if (semop(semid, &sb, 1) < 0) {
2754
    switch (errno) {
2755
      case EAGAIN:
2756
        log_error("cookie dec: semid %d: semop failed for cookie "
2757
            "0x%" PRIx32 ": "
2758
            "incorrect semaphore state",
2759
            semid, cookie);
2760
        break;
2761
      default:
2762
        log_error("cookie dec: semid %d: semop failed for cookie "
2763
            "0x%" PRIx32 ": %s",
2764
            semid, cookie, strerror(errno));
2765
        break;
2766
    }
2767
    return 0;
2768
  }
2769
2770
  if (val < 0)
2771
    log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) decremented.",
2772
             cookie, semid);
2773
  else
2774
    log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) decremented to %d",
2775
             cookie, semid, val - 1);
2776
  return 1;
2777
}
2778
2779
static int _udev_notify_sem_destroy(uint32_t cookie, int semid)
2780
{
2781
  if (semctl(semid, 0, IPC_RMID, 0) < 0) {
2782
    log_error("Could not cleanup notification semaphore "
2783
        "identified by cookie value %" PRIu32 " (0x%x): %s",
2784
        cookie, cookie, strerror(errno));
2785
    return 0;
2786
  }
2787
2788
  log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) destroyed", cookie,
2789
           semid);
2790
2791
  return 1;
2792
}
2793
2794
static int _udev_notify_sem_create(uint32_t *cookie, int *semid)
2795
{
2796
  int fd;
2797
  int gen_semid;
2798
  int val;
2799
  uint16_t base_cookie;
2800
  uint32_t gen_cookie;
2801
  union semun sem_arg;
2802
2803
  if ((fd = open("/dev/urandom", O_RDONLY)) < 0) {
2804
    log_error("Failed to open /dev/urandom "
2805
        "to create random cookie value");
2806
    *cookie = 0;
2807
    return 0;
2808
  }
2809
2810
  /* Generate random cookie value. Be sure it is unique and non-zero. */
2811
  do {
2812
    /* FIXME Handle non-error returns from read(). Move _io() into libdm? */
2813
    if (read(fd, &base_cookie, sizeof(base_cookie)) != sizeof(base_cookie)) {
2814
      log_error("Failed to initialize notification cookie");
2815
      goto bad;
2816
    }
2817
2818
    gen_cookie = DM_COOKIE_MAGIC << 16 | base_cookie;
2819
2820
    if (base_cookie && (gen_semid = semget((key_t) gen_cookie,
2821
            1, 0600 | IPC_CREAT | IPC_EXCL)) < 0) {
2822
      switch (errno) {
2823
        case EEXIST:
2824
          /* if the semaphore key exists, we
2825
           * simply generate another random one */
2826
          base_cookie = 0;
2827
          break;
2828
        case ENOMEM:
2829
          log_error("Not enough memory to create "
2830
              "notification semaphore");
2831
          goto bad;
2832
        case ENOSPC:
2833
          log_error("Limit for the maximum number "
2834
              "of semaphores reached. You can "
2835
              "check and set the limits in "
2836
              "/proc/sys/kernel/sem.");
2837
          goto bad;
2838
        default:
2839
          log_error("Failed to create notification "
2840
              "semaphore: %s", strerror(errno));
2841
          goto bad;
2842
      }
2843
    }
2844
  } while (!base_cookie);
2845
2846
  log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) created",
2847
           gen_cookie, gen_semid);
2848
2849
  sem_arg.val = 1;
2850
2851
  if (semctl(gen_semid, 0, SETVAL, sem_arg) < 0) {
2852
    log_error("cookie create: semid %d: semctl failed: %s", gen_semid, strerror(errno));
2853
    /* We have to destroy just created semaphore
2854
     * so it won't stay in the system. */
2855
    (void) _udev_notify_sem_destroy(gen_cookie, gen_semid);
2856
    goto bad;
2857
  }
2858
2859
  if ((val = semctl(gen_semid, 0, GETVAL)) < 0) {
2860
    log_error("cookie create: semid %d: semctl GETVAL failed for "
2861
        "cookie 0x%" PRIx32 ": %s",
2862
        gen_semid, gen_cookie, strerror(errno));
2863
    (void) _udev_notify_sem_destroy(gen_cookie, gen_semid);
2864
    goto bad;
2865
  }
2866
2867
  log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented to %d",
2868
           gen_cookie, gen_semid, val);
2869
2870
  if (close(fd))
2871
    stack;
2872
2873
  *semid = gen_semid;
2874
  *cookie = gen_cookie;
2875
2876
  return 1;
2877
2878
bad:
2879
  if (close(fd))
2880
    stack;
2881
2882
  *cookie = 0;
2883
2884
  return 0;
2885
}
2886
2887
int dm_udev_create_cookie(uint32_t *cookie)
2888
{
2889
  int semid;
2890
2891
  if (!dm_udev_get_sync_support()) {
2892
    *cookie = 0;
2893
    return 1;
2894
  }
2895
2896
  return _udev_notify_sem_create(cookie, &semid);
2897
}
2898
2899
static const char *_task_type_disp(int type)
2900
{
2901
  switch(type) {
2902
  case DM_DEVICE_CREATE:
2903
    return "CREATE";
2904
  case DM_DEVICE_RELOAD:
2905
    return "RELOAD";
2906
  case DM_DEVICE_REMOVE:
2907
    return "REMOVE";
2908
  case DM_DEVICE_REMOVE_ALL:
2909
    return "REMOVE_ALL";
2910
  case DM_DEVICE_SUSPEND:
2911
    return "SUSPEND";
2912
  case DM_DEVICE_RESUME:
2913
    return "RESUME";
2914
  case DM_DEVICE_INFO:
2915
    return "INFO";
2916
  case DM_DEVICE_DEPS:
2917
    return "DEPS";
2918
  case DM_DEVICE_RENAME:
2919
    return "RENAME";
2920
  case DM_DEVICE_VERSION:
2921
    return "VERSION";
2922
  case DM_DEVICE_STATUS:
2923
    return "STATUS";
2924
  case DM_DEVICE_TABLE:
2925
    return "TABLE";
2926
  case DM_DEVICE_WAITEVENT:
2927
    return "WAITEVENT";
2928
  case DM_DEVICE_LIST:
2929
    return "LIST";
2930
  case DM_DEVICE_CLEAR:
2931
    return "CLEAR";
2932
  case DM_DEVICE_MKNODES:
2933
    return "MKNODES";
2934
  case DM_DEVICE_LIST_VERSIONS:
2935
    return "LIST_VERSIONS";
2936
  case DM_DEVICE_TARGET_MSG:
2937
    return "TARGET_MSG";
2938
  case DM_DEVICE_SET_GEOMETRY:
2939
    return "SET_GEOMETRY";
2940
  }
2941
  return "unknown";
2942
}
2943
2944
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)
2945
{
2946
  int semid;
2947
2948
  _set_cookie_flags(dmt, flags);
2949
2950
  if (!dm_udev_get_sync_support()) {
2951
    *cookie = 0;
2952
    dmt->cookie_set = 1;
2953
    return 1;
2954
  }
2955
2956
  if (*cookie) {
2957
    if (!_get_cookie_sem(*cookie, &semid))
2958
      goto_bad;
2959
  } else if (!_udev_notify_sem_create(cookie, &semid))
2960
    goto_bad;
2961
2962
  if (!_udev_notify_sem_inc(*cookie, semid)) {
2963
    log_error("Could not set notification semaphore "
2964
        "identified by cookie value %" PRIu32 " (0x%x)",
2965
        *cookie, *cookie);
2966
    goto bad;
2967
  }
2968
2969
  dmt->event_nr |= ~DM_UDEV_FLAGS_MASK & *cookie;
2970
  dmt->cookie_set = 1;
2971
2972
  log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) assigned to "
2973
           "%s task(%d) with flags%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s (0x%" PRIx16 ")",
2974
           *cookie, semid, _task_type_disp(dmt->type), dmt->type,
2975
           (flags & DM_UDEV_DISABLE_DM_RULES_FLAG) ? " DISABLE_DM_RULES" : "",
2976
           (flags & DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG) ? " DISABLE_SUBSYSTEM_RULES" : "",
2977
           (flags & DM_UDEV_DISABLE_DISK_RULES_FLAG) ? " DISABLE_DISK_RULES" : "",
2978
           (flags & DM_UDEV_DISABLE_OTHER_RULES_FLAG) ? " DISABLE_OTHER_RULES" : "",
2979
           (flags & DM_UDEV_LOW_PRIORITY_FLAG) ? " LOW_PRIORITY" : "",
2980
           (flags & DM_UDEV_DISABLE_LIBRARY_FALLBACK) ? " DISABLE_LIBRARY_FALLBACK" : "",
2981
           (flags & DM_UDEV_PRIMARY_SOURCE_FLAG) ? " PRIMARY_SOURCE" : "",
2982
           (flags & DM_SUBSYSTEM_UDEV_FLAG0) ? " SUBSYSTEM_0" : "",
2983
           (flags & DM_SUBSYSTEM_UDEV_FLAG1) ? " SUBSYSTEM_1" : "",
2984
           (flags & DM_SUBSYSTEM_UDEV_FLAG2) ? " SUBSYSTEM_2" : "",
2985
           (flags & DM_SUBSYSTEM_UDEV_FLAG3) ? " SUBSYSTEM_3" : "",
2986
           (flags & DM_SUBSYSTEM_UDEV_FLAG4) ? " SUBSYSTEM_4" : "",
2987
           (flags & DM_SUBSYSTEM_UDEV_FLAG5) ? " SUBSYSTEM_5" : "",
2988
           (flags & DM_SUBSYSTEM_UDEV_FLAG6) ? " SUBSYSTEM_6" : "",
2989
           (flags & DM_SUBSYSTEM_UDEV_FLAG7) ? " SUBSYSTEM_7" : "",
2990
           flags);
2991
2992
  return 1;
2993
2994
bad:
2995
  dmt->event_nr = 0;
2996
  return 0;
2997
}
2998
2999
int dm_udev_complete(uint32_t cookie)
3000
{
3001
  int semid;
3002
3003
  if (!cookie || !dm_udev_get_sync_support())
3004
    return 1;
3005
3006
  if (!_get_cookie_sem(cookie, &semid))
3007
    return_0;
3008
3009
  if (!_udev_notify_sem_dec(cookie, semid)) {
3010
    log_error("Could not signal waiting process using notification "
3011
        "semaphore identified by cookie value %" PRIu32 " (0x%x)",
3012
        cookie, cookie);
3013
    return 0;
3014
  }
3015
3016
  return 1;
3017
}
3018
3019
/*
3020
 * If *nowait is set, return immediately leaving it set if the semaphore
3021
 * is not ready to be decremented to 0.  *nowait is cleared if the wait
3022
 * succeeds.
3023
 */
3024
static int _udev_wait(uint32_t cookie, int *nowait)
3025
{
3026
  int semid;
3027
  struct sembuf sb = {0, 0, 0};
3028
  int val;
3029
3030
  if (!cookie || !dm_udev_get_sync_support())
3031
    return 1;
3032
3033
  if (!_get_cookie_sem(cookie, &semid))
3034
    return_0;
3035
3036
  /* Return immediately if the semaphore value exceeds 1? */
3037
  if (*nowait) {
3038
    if ((val = semctl(semid, 0, GETVAL)) < 0) {
3039
      log_error("semid %d: semctl GETVAL failed for "
3040
          "cookie 0x%" PRIx32 ": %s",
3041
          semid, cookie, strerror(errno));
3042
      return 0;
3043
    }
3044
3045
    if (val > 1)
3046
      return 1;
3047
3048
    *nowait = 0;
3049
  }
3050
3051
  if (!_udev_notify_sem_dec(cookie, semid)) {
3052
    log_error("Failed to set a proper state for notification "
3053
        "semaphore identified by cookie value %" PRIu32 " (0x%x) "
3054
        "to initialize waiting for incoming notifications.",
3055
        cookie, cookie);
3056
    (void) _udev_notify_sem_destroy(cookie, semid);
3057
    return 0;
3058
  }
3059
3060
  log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) waiting for zero",
3061
           cookie, semid);
3062
3063
repeat_wait:
3064
  if (semop(semid, &sb, 1) < 0) {
3065
    if (errno == EINTR)
3066
      goto repeat_wait;
3067
    else if (errno == EIDRM)
3068
      return 1;
3069
3070
    log_error("Could not set wait state for notification semaphore "
3071
        "identified by cookie value %" PRIu32 " (0x%x): %s",
3072
        cookie, cookie, strerror(errno));
3073
    (void) _udev_notify_sem_destroy(cookie, semid);
3074
    return 0;
3075
  }
3076
3077
  return _udev_notify_sem_destroy(cookie, semid);
3078
}
3079
3080
int dm_udev_wait(uint32_t cookie)
3081
{
3082
  int nowait = 0;
3083
  int r = _udev_wait(cookie, &nowait);
3084
3085
  update_devs();
3086
3087
  return r;
3088
}
3089
3090
int dm_udev_wait_immediate(uint32_t cookie, int *ready)
3091
{
3092
  int nowait = 1;
3093
  int r = _udev_wait(cookie, &nowait);
3094
3095
  if (r && nowait) {
3096
    *ready = 0;
3097
    return 1;
3098
  }
3099
3100
  update_devs();
3101
  *ready = 1;
3102
3103
  return r;
3104
}
3105
#endif    /* UDEV_SYNC_SUPPORT */