Coverage Report

Created: 2026-05-30 06:05

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