2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
5 * This file is part of the device-mapper userspace tools.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 #include "libdm-targets.h"
18 #include "libdm-common.h"
23 #include <sys/param.h>
24 #include <sys/ioctl.h>
28 #ifdef UDEV_SYNC_SUPPORT
29 # include <sys/types.h>
36 # include <linux/fs.h>
40 # include <selinux/selinux.h>
42 #ifdef HAVE_SELINUX_LABEL_H
43 # include <selinux/label.h>
46 #define DM_DEFAULT_NAME_MANGLING_MODE_ENV_VAR_NAME "DM_DEFAULT_NAME_MANGLING_MODE"
48 #define DEV_DIR "/dev/"
50 #ifdef UDEV_SYNC_SUPPORT
51 #ifdef _SEM_SEMUN_UNDEFINED
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 */
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 */
66 #define DM_MAX_UUID_PREFIX_LEN 15
67 static char _default_uuid_prefix
[DM_MAX_UUID_PREFIX_LEN
+ 1] = "LVM-";
69 static int _verbose
= 0;
70 static int _suspended_dev_counter
= 0;
71 static dm_string_mangling_t _name_mangling_mode
= DEFAULT_DM_NAME_MANGLING
;
73 #ifdef HAVE_SELINUX_LABEL_H
74 static struct selabel_handle
*_selabel_handle
= NULL
;
77 #ifdef UDEV_SYNC_SUPPORT
78 static int _semaphore_supported
= -1;
79 static int _udev_running
= -1;
80 static int _sync_with_udev
= 1;
81 static int _udev_checking
= 1;
84 void dm_lib_init(void)
88 env
= getenv(DM_DEFAULT_NAME_MANGLING_MODE_ENV_VAR_NAME
);
90 if (!strcasecmp(env
, "none"))
91 _name_mangling_mode
= DM_STRING_MANGLING_NONE
;
92 else if (!strcasecmp(env
, "auto"))
93 _name_mangling_mode
= DM_STRING_MANGLING_AUTO
;
94 else if (!strcasecmp(env
, "hex"))
95 _name_mangling_mode
= DM_STRING_MANGLING_HEX
;
97 _name_mangling_mode
= DEFAULT_DM_NAME_MANGLING
;
101 * Library users can provide their own logging
105 __attribute__((format(printf
, 5, 0)))
106 static void _default_log_line(int level
,
107 const char *file
__attribute__((unused
)),
108 int line
__attribute__((unused
)), int dm_errno
,
109 const char *f
, va_list ap
)
111 int use_stderr
= level
& _LOG_STDERR
;
113 level
&= ~_LOG_STDERR
;
115 if (level
> _LOG_WARN
&& !_verbose
)
118 if (level
< _LOG_WARN
)
119 vfprintf(stderr
, f
, ap
);
121 vfprintf(use_stderr
? stderr
: stdout
, f
, ap
);
123 if (level
< _LOG_WARN
)
124 fprintf(stderr
, "\n");
126 fprintf(use_stderr
? stderr
: stdout
, "\n");
129 __attribute__((format(printf
, 5, 6)))
130 static void _default_log_with_errno(int level
,
131 const char *file
__attribute__((unused
)),
132 int line
__attribute__((unused
)), int dm_errno
,
138 _default_log_line(level
, file
, line
, dm_errno
, f
, ap
);
142 __attribute__((format(printf
, 4, 5)))
143 static void _default_log(int level
, const char *file
,
144 int line
, const char *f
, ...)
149 _default_log_line(level
, file
, line
, 0, f
, ap
);
153 dm_log_fn dm_log
= _default_log
;
154 dm_log_with_errno_fn dm_log_with_errno
= _default_log_with_errno
;
156 void dm_log_init(dm_log_fn fn
)
161 dm_log
= _default_log
;
163 dm_log_with_errno
= _default_log_with_errno
;
166 int dm_log_is_non_default(void)
168 return (dm_log
== _default_log
) ? 0 : 1;
171 void dm_log_with_errno_init(dm_log_with_errno_fn fn
)
174 dm_log_with_errno
= fn
;
176 dm_log_with_errno
= _default_log_with_errno
;
178 dm_log
= _default_log
;
181 void dm_log_init_verbose(int level
)
186 static void _build_dev_path(char *buffer
, size_t len
, const char *dev_name
)
188 /* If there's a /, assume caller knows what they're doing */
189 if (strchr(dev_name
, '/'))
190 snprintf(buffer
, len
, "%s", dev_name
);
192 snprintf(buffer
, len
, "%s/%s", _dm_dir
, dev_name
);
195 int dm_get_library_version(char *version
, size_t size
)
197 strncpy(version
, DM_LIB_VERSION
, size
);
201 void inc_suspended(void)
203 _suspended_dev_counter
++;
204 log_debug("Suspended device counter increased to %d", _suspended_dev_counter
);
207 void dec_suspended(void)
209 if (!_suspended_dev_counter
) {
210 log_error("Attempted to decrement suspended device counter below zero.");
214 _suspended_dev_counter
--;
215 log_debug("Suspended device counter reduced to %d", _suspended_dev_counter
);
218 int dm_get_suspended_counter(void)
220 return _suspended_dev_counter
;
223 int dm_set_name_mangling_mode(dm_string_mangling_t name_mangling_mode
)
225 _name_mangling_mode
= name_mangling_mode
;
230 dm_string_mangling_t
dm_get_name_mangling_mode(void)
232 return _name_mangling_mode
;
235 struct dm_task
*dm_task_create(int type
)
237 struct dm_task
*dmt
= dm_zalloc(sizeof(*dmt
));
240 log_error("dm_task_create: malloc(%" PRIsize_t
") failed",
245 if (!dm_check_version()) {
253 dmt
->allow_default_major_fallback
= 1;
254 dmt
->uid
= DM_DEVICE_UID
;
255 dmt
->gid
= DM_DEVICE_GID
;
256 dmt
->mode
= DM_DEVICE_MODE
;
257 dmt
->no_open_count
= 0;
258 dmt
->read_ahead
= DM_READ_AHEAD_AUTO
;
259 dmt
->read_ahead_flags
= 0;
262 dmt
->query_inactive_table
= 0;
264 dmt
->secure_data
= 0;
270 * Find the name associated with a given device number by scanning _dm_dir.
272 static int _find_dm_name_of_device(dev_t st_rdev
, char *buf
, size_t buf_len
)
276 struct dirent
*dirent
;
281 if (!(d
= opendir(_dm_dir
))) {
282 log_sys_error("opendir", _dm_dir
);
286 while ((dirent
= readdir(d
))) {
287 name
= dirent
->d_name
;
289 if (!strcmp(name
, ".") || !strcmp(name
, ".."))
292 if (dm_snprintf(path
, sizeof(path
), "%s/%s", _dm_dir
,
294 log_error("Couldn't create path for %s", name
);
301 if (st
.st_rdev
== st_rdev
) {
302 strncpy(buf
, name
, buf_len
);
309 log_sys_error("closedir", _dm_dir
);
314 static int _is_whitelisted_char(char c
)
317 * Actually, DM supports any character in a device name.
318 * This whitelist is just for proper integration with udev.
320 if ((c
>= '0' && c
<= '9') ||
321 (c
>= 'A' && c
<= 'Z') ||
322 (c
>= 'a' && c
<= 'z') ||
323 strchr("#+-.:=@_", c
) != NULL
)
329 int check_multiple_mangled_name_allowed(dm_string_mangling_t mode
, const char *name
)
331 if (mode
== DM_STRING_MANGLING_AUTO
&& strstr(name
, "\\x5cx")) {
332 log_error("The name \"%s\" seems to be mangled more than once. "
333 "This is not allowed in auto mode.", name
);
341 * Mangle all characters in the input string which are not on a whitelist
342 * with '\xNN' format where NN is the hex value of the character.
344 int mangle_name(const char *str
, size_t len
, char *buf
,
345 size_t buf_len
, dm_string_mangling_t mode
)
347 int need_mangling
= -1; /* -1 don't know yet, 0 no, 1 yes */
353 /* Is there anything to do at all? */
357 if (buf_len
< DM_NAME_LEN
) {
358 log_error(INTERNAL_ERROR
"mangle_name: supplied buffer too small");
362 if (mode
== DM_STRING_MANGLING_NONE
)
363 mode
= DM_STRING_MANGLING_AUTO
;
365 for (i
= 0, j
= 0; str
[i
]; i
++) {
366 if (mode
== DM_STRING_MANGLING_AUTO
) {
368 * Detect already mangled part of the string and keep it.
369 * Return error on mixture of mangled/not mangled!
371 if (str
[i
] == '\\' && str
[i
+1] == 'x') {
372 if ((len
- i
< 4) || (need_mangling
== 1))
377 memcpy(&buf
[j
], &str
[i
], 4);
385 if (_is_whitelisted_char(str
[i
])) {
386 /* whitelisted, keep it. */
393 * Not on a whitelist, mangle it.
394 * Return error on mixture of mangled/not mangled
395 * unless a DM_STRING_MANGLING_HEX is used!.
397 if ((mode
!= DM_STRING_MANGLING_HEX
) && (need_mangling
== 0))
402 sprintf(&buf
[j
], "\\x%02x", (unsigned char) str
[i
]);
413 /* All chars in the string whitelisted? */
414 if (need_mangling
== -1)
417 return need_mangling
;
420 log_error("The name \"%s\" contains mixed mangled and unmangled "
421 "characters or it's already mangled improperly.", str
);
424 log_error("Mangled form of the name too long for \"%s\".", str
);
429 * Try to unmangle supplied string.
430 * Return value: -1 on error, 0 when no unmangling needed, 1 when unmangling applied
432 int unmangle_name(const char *str
, size_t len
, char *buf
,
433 size_t buf_len
, dm_string_mangling_t mode
)
435 int strict
= mode
!= DM_STRING_MANGLING_NONE
;
436 char str_rest
[DM_NAME_LEN
];
444 /* Is there anything to do at all? */
448 if (buf_len
< DM_NAME_LEN
) {
449 log_error(INTERNAL_ERROR
"unmangle_name: supplied buffer too small");
453 for (i
= 0, j
= 0; str
[i
]; i
++, j
++) {
454 if (strict
&& !(_is_whitelisted_char(str
[i
]) || str
[i
]=='\\')) {
455 log_error("The name \"%s\" should be mangled but "
456 "it contains blacklisted characters.", str
);
461 if (str
[i
] == '\\' && str
[i
+1] == 'x') {
462 if (!sscanf(&str
[i
+2], "%2x%s", &code
, str_rest
)) {
463 log_debug("Hex encoding mismatch detected in \"%s\" "
464 "while trying to unmangle it.", str
);
467 buf
[j
] = (unsigned char) code
;
469 /* skip the encoded part we've just decoded! */
472 /* unmangling applied */
483 static int _dm_task_set_name(struct dm_task
*dmt
, const char *name
,
484 dm_string_mangling_t mangling_mode
)
486 char mangled_name
[DM_NAME_LEN
];
489 dm_free(dmt
->dev_name
);
490 dmt
->dev_name
= NULL
;
491 dm_free(dmt
->mangled_dev_name
);
492 dmt
->mangled_dev_name
= NULL
;
494 if (strlen(name
) >= DM_NAME_LEN
) {
495 log_error("Name \"%s\" too long.", name
);
499 if (!check_multiple_mangled_name_allowed(mangling_mode
, name
))
502 if (mangling_mode
!= DM_STRING_MANGLING_NONE
&&
503 (r
= mangle_name(name
, strlen(name
), mangled_name
,
504 sizeof(mangled_name
), mangling_mode
)) < 0) {
505 log_error("Failed to mangle device name \"%s\".", name
);
509 /* Store mangled_dev_name only if it differs from dev_name! */
511 log_debug("Device name mangled [%s]: %s --> %s",
512 mangling_mode
== DM_STRING_MANGLING_AUTO
? "auto" : "hex",
514 if (!(dmt
->mangled_dev_name
= dm_strdup(mangled_name
))) {
515 log_error("_dm_task_set_name: dm_strdup(%s) failed", mangled_name
);
520 if (!(dmt
->dev_name
= dm_strdup(name
))) {
521 log_error("_dm_task_set_name: strdup(%s) failed", name
);
528 static int _dm_task_set_name_from_path(struct dm_task
*dmt
, const char *path
,
532 struct stat st1
, st2
;
533 const char *final_name
;
535 if (dmt
->type
== DM_DEVICE_CREATE
) {
536 log_error("Name \"%s\" invalid. It contains \"/\".", path
);
540 if (stat(path
, &st1
)) {
541 log_error("Device %s not found", path
);
546 * If supplied path points to same device as last component
547 * under /dev/mapper, use that name directly. Otherwise call
548 * _find_dm_name_of_device() to scan _dm_dir for a match.
550 if (dm_snprintf(buf
, sizeof(buf
), "%s/%s", _dm_dir
, name
) == -1) {
551 log_error("Couldn't create path for %s", name
);
555 if (!stat(buf
, &st2
) && (st1
.st_rdev
== st2
.st_rdev
))
557 else if (_find_dm_name_of_device(st1
.st_rdev
, buf
, sizeof(buf
)))
560 log_error("Device %s not found", name
);
564 /* This is an already existing path - do not mangle! */
565 return _dm_task_set_name(dmt
, final_name
, DM_STRING_MANGLING_NONE
);
568 int dm_task_set_name(struct dm_task
*dmt
, const char *name
)
572 /* Path supplied for existing device? */
573 if ((pos
= strrchr(name
, '/')))
574 return _dm_task_set_name_from_path(dmt
, name
, pos
+ 1);
576 return _dm_task_set_name(dmt
, name
, dm_get_name_mangling_mode());
579 const char *dm_task_get_name(const struct dm_task
*dmt
)
581 return (dmt
->dmi
.v4
->name
);
584 char *dm_task_get_name_mangled(const struct dm_task
*dmt
)
586 const char *s
= dm_task_get_name(dmt
);
587 char buf
[DM_NAME_LEN
];
591 if ((r
= mangle_name(s
, strlen(s
), buf
, sizeof(buf
),
592 dm_get_name_mangling_mode())) < 0)
593 log_error("Failed to mangle device name \"%s\".", s
);
594 else if (!(rs
= r
? dm_strdup(buf
) : dm_strdup(s
)))
595 log_error("dm_task_get_name_mangled: dm_strdup failed");
600 char *dm_task_get_name_unmangled(const struct dm_task
*dmt
)
602 const char *s
= dm_task_get_name(dmt
);
603 char buf
[DM_NAME_LEN
];
608 * Unless the mode used is 'none', the name
609 * is *already* unmangled on ioctl return!
611 if (dm_get_name_mangling_mode() == DM_STRING_MANGLING_NONE
&&
612 (r
= unmangle_name(s
, strlen(s
), buf
, sizeof(buf
),
613 dm_get_name_mangling_mode())) < 0)
614 log_error("Failed to unmangle device name \"%s\".", s
);
615 else if (!(rs
= r
? dm_strdup(buf
) : dm_strdup(s
)))
616 log_error("dm_task_get_name_unmangled: dm_strdup failed");
621 int dm_task_set_newname(struct dm_task
*dmt
, const char *newname
)
623 dm_string_mangling_t mangling_mode
= dm_get_name_mangling_mode();
624 char mangled_name
[DM_NAME_LEN
];
627 if (strchr(newname
, '/')) {
628 log_error("Name \"%s\" invalid. It contains \"/\".", newname
);
632 if (strlen(newname
) >= DM_NAME_LEN
) {
633 log_error("Name \"%s\" too long", newname
);
637 if (!check_multiple_mangled_name_allowed(mangling_mode
, newname
))
640 if (mangling_mode
!= DM_STRING_MANGLING_NONE
&&
641 (r
= mangle_name(newname
, strlen(newname
), mangled_name
,
642 sizeof(mangled_name
), mangling_mode
)) < 0) {
643 log_error("Failed to mangle new device name \"%s\"", newname
);
648 log_debug("New device name mangled [%s]: %s --> %s",
649 mangling_mode
== DM_STRING_MANGLING_AUTO
? "auto" : "hex",
650 newname
, mangled_name
);
651 newname
= mangled_name
;
654 if (!(dmt
->newname
= dm_strdup(newname
))) {
655 log_error("dm_task_set_newname: strdup(%s) failed", newname
);
664 int dm_task_set_uuid(struct dm_task
*dmt
, const char *uuid
)
668 if (!(dmt
->uuid
= dm_strdup(uuid
))) {
669 log_error("dm_task_set_uuid: strdup(%s) failed", uuid
);
676 int dm_task_set_major(struct dm_task
*dmt
, int major
)
679 dmt
->allow_default_major_fallback
= 0;
684 int dm_task_set_minor(struct dm_task
*dmt
, int minor
)
691 int dm_task_set_major_minor(struct dm_task
*dmt
, int major
, int minor
,
692 int allow_default_major_fallback
)
696 dmt
->allow_default_major_fallback
= allow_default_major_fallback
;
701 int dm_task_set_uid(struct dm_task
*dmt
, uid_t uid
)
708 int dm_task_set_gid(struct dm_task
*dmt
, gid_t gid
)
715 int dm_task_set_mode(struct dm_task
*dmt
, mode_t mode
)
722 int dm_task_enable_checks(struct dm_task
*dmt
)
724 dmt
->enable_checks
= 1;
729 int dm_task_add_target(struct dm_task
*dmt
, uint64_t start
, uint64_t size
,
730 const char *ttype
, const char *params
)
732 struct target
*t
= create_target(start
, size
, ttype
, params
);
737 dmt
->head
= dmt
->tail
= t
;
747 static int _selabel_lookup(const char *path
, mode_t mode
,
748 security_context_t
*scontext
)
750 #ifdef HAVE_SELINUX_LABEL_H
751 if (!_selabel_handle
&&
752 !(_selabel_handle
= selabel_open(SELABEL_CTX_FILE
, NULL
, 0))) {
753 log_error("selabel_open failed: %s", strerror(errno
));
757 if (selabel_lookup(_selabel_handle
, scontext
, path
, mode
)) {
758 log_debug("selabel_lookup failed for %s: %s",
759 path
, strerror(errno
));
763 if (matchpathcon(path
, mode
, scontext
)) {
764 log_debug("matchpathcon failed for %s: %s",
765 path
, strerror(errno
));
773 int dm_prepare_selinux_context(const char *path
, mode_t mode
)
776 security_context_t scontext
= NULL
;
778 if (is_selinux_enabled() <= 0)
782 if (!_selabel_lookup(path
, mode
, &scontext
))
785 log_debug("Preparing SELinux context for %s to %s.", path
, scontext
);
788 log_debug("Resetting SELinux context to default value.");
790 if (setfscreatecon(scontext
) < 0) {
791 log_sys_error("setfscreatecon", path
);
801 int dm_set_selinux_context(const char *path
, mode_t mode
)
804 security_context_t scontext
;
806 if (is_selinux_enabled() <= 0)
809 if (!_selabel_lookup(path
, mode
, &scontext
))
812 log_debug("Setting SELinux context for %s to %s.", path
, scontext
);
814 if ((lsetfilecon(path
, scontext
) < 0) && (errno
!= ENOTSUP
)) {
815 log_sys_error("lsetfilecon", path
);
825 void selinux_release(void)
827 #ifdef HAVE_SELINUX_LABEL_H
829 selabel_close(_selabel_handle
);
830 _selabel_handle
= NULL
;
834 static int _warn_if_op_needed(int warn_if_udev_failed
)
836 return warn_if_udev_failed
&& dm_udev_get_sync_support() && dm_udev_get_checking();
839 static int _add_dev_node(const char *dev_name
, uint32_t major
, uint32_t minor
,
840 uid_t uid
, gid_t gid
, mode_t mode
, int warn_if_udev_failed
)
844 dev_t dev
= MKDEV(major
, minor
);
847 _build_dev_path(path
, sizeof(path
), dev_name
);
849 if (stat(path
, &info
) >= 0) {
850 if (!S_ISBLK(info
.st_mode
)) {
851 log_error("A non-block device file at '%s' "
852 "is already present", path
);
856 /* If right inode already exists we don't touch uid etc. */
857 if (info
.st_rdev
== dev
)
860 if (unlink(path
) < 0) {
861 log_error("Unable to unlink device node for '%s'",
865 } else if (_warn_if_op_needed(warn_if_udev_failed
))
866 log_warn("%s not set up by udev: Falling back to direct "
867 "node creation.", path
);
869 (void) dm_prepare_selinux_context(path
, S_IFBLK
);
871 if (mknod(path
, S_IFBLK
| mode
, dev
) < 0) {
872 log_error("%s: mknod for %s failed: %s", path
, dev_name
, strerror(errno
));
874 (void) dm_prepare_selinux_context(NULL
, 0);
878 (void) dm_prepare_selinux_context(NULL
, 0);
880 if (chown(path
, uid
, gid
) < 0) {
881 log_sys_error("chown", path
);
885 log_debug("Created %s", path
);
890 static int _rm_dev_node(const char *dev_name
, int warn_if_udev_failed
)
895 _build_dev_path(path
, sizeof(path
), dev_name
);
897 if (stat(path
, &info
) < 0)
899 else if (_warn_if_op_needed(warn_if_udev_failed
))
900 log_warn("Node %s was not removed by udev. "
901 "Falling back to direct node removal.", path
);
903 if (unlink(path
) < 0) {
904 log_error("Unable to unlink device node for '%s'", dev_name
);
908 log_debug("Removed %s", path
);
913 static int _rename_dev_node(const char *old_name
, const char *new_name
,
914 int warn_if_udev_failed
)
916 char oldpath
[PATH_MAX
];
917 char newpath
[PATH_MAX
];
920 _build_dev_path(oldpath
, sizeof(oldpath
), old_name
);
921 _build_dev_path(newpath
, sizeof(newpath
), new_name
);
923 if (stat(newpath
, &info
) == 0) {
924 if (!S_ISBLK(info
.st_mode
)) {
925 log_error("A non-block device file at '%s' "
926 "is already present", newpath
);
929 else if (_warn_if_op_needed(warn_if_udev_failed
)) {
930 if (stat(oldpath
, &info
) < 0 &&
932 /* assume udev already deleted this */
935 log_warn("The node %s should have been renamed to %s "
936 "by udev but old node is still present. "
937 "Falling back to direct old node removal.",
939 return _rm_dev_node(old_name
, 0);
943 if (unlink(newpath
) < 0) {
944 if (errno
== EPERM
) {
945 /* devfs, entry has already been renamed */
948 log_error("Unable to unlink device node for '%s'",
953 else if (_warn_if_op_needed(warn_if_udev_failed
))
954 log_warn("The node %s should have been renamed to %s "
955 "by udev but new node is not present. "
956 "Falling back to direct node rename.",
959 if (rename(oldpath
, newpath
) < 0) {
960 log_error("Unable to rename device node from '%s' to '%s'",
965 log_debug("Renamed %s to %s", oldpath
, newpath
);
971 static int _open_dev_node(const char *dev_name
)
976 _build_dev_path(path
, sizeof(path
), dev_name
);
978 if ((fd
= open(path
, O_RDONLY
, 0)) < 0)
979 log_sys_error("open", path
);
984 int get_dev_node_read_ahead(const char *dev_name
, uint32_t major
, uint32_t minor
,
985 uint32_t *read_ahead
)
991 long read_ahead_long
;
994 * If we know the device number, use sysfs if we can.
995 * Otherwise use BLKRAGET ioctl.
997 if (*_sysfs_dir
&& major
!= 0) {
998 if (dm_snprintf(_path0
, sizeof(_path0
), "%sdev/block/%" PRIu32
999 ":%" PRIu32
"/bdi/read_ahead_kb", _sysfs_dir
,
1000 major
, minor
) < 0) {
1001 log_error("Failed to build sysfs_path.");
1005 if ((fd
= open(_path0
, O_RDONLY
, 0)) != -1) {
1006 /* Reading from sysfs, expecting number\n */
1007 if ((len
= read(fd
, buf
, sizeof(buf
) - 1)) < 1) {
1008 log_sys_error("read", _path0
);
1011 buf
[len
] = 0; /* kill \n and ensure \0 */
1012 *read_ahead
= atoi(buf
) * 2;
1013 log_debug("%s (%d:%d): read ahead is %" PRIu32
,
1014 dev_name
, major
, minor
, *read_ahead
);
1018 log_sys_debug("close", _path0
);
1023 log_sys_debug("open", _path0
);
1024 /* Fall back to use dev_name */
1028 * Open/close dev_name may block the process
1029 * (i.e. overfilled thin pool volume)
1032 log_error("Empty device name passed to BLKRAGET");
1036 if ((fd
= _open_dev_node(dev_name
)) < 0)
1039 if (ioctl(fd
, BLKRAGET
, &read_ahead_long
)) {
1040 log_sys_error("BLKRAGET", dev_name
);
1044 *read_ahead
= (uint32_t) read_ahead_long
;
1045 log_debug("%s: read ahead is %" PRIu32
, dev_name
, *read_ahead
);
1049 log_sys_debug("close", dev_name
);
1054 static int _set_read_ahead(const char *dev_name
, uint32_t major
, uint32_t minor
,
1055 uint32_t read_ahead
)
1061 long read_ahead_long
= (long) read_ahead
;
1063 log_debug("%s (%d:%d): Setting read ahead to %" PRIu32
, dev_name
,
1064 major
, minor
, read_ahead
);
1067 * If we know the device number, use sysfs if we can.
1068 * Otherwise use BLKRASET ioctl. RA is set after resume.
1070 if (*_sysfs_dir
&& major
!= 0) {
1071 if (dm_snprintf(_path0
, sizeof(_path0
), "%sdev/block/%" PRIu32
1072 ":%" PRIu32
"/bdi/read_ahead_kb",
1073 _sysfs_dir
, major
, minor
) < 0) {
1074 log_error("Failed to build sysfs_path.");
1078 /* Sysfs is kB based, round up to kB */
1079 if ((len
= dm_snprintf(buf
, sizeof(buf
), "%" PRIu32
,
1080 (read_ahead
+ 1) / 2)) < 0) {
1081 log_error("Failed to build size in kB.");
1085 if ((fd
= open(_path0
, O_WRONLY
, 0)) != -1) {
1086 if (write(fd
, buf
, len
) < len
) {
1087 log_sys_error("write", _path0
);
1092 log_sys_debug("close", _path0
);
1097 log_sys_debug("open", _path0
);
1098 /* Fall back to use dev_name */
1102 log_error("Empty device name passed to BLKRAGET");
1106 if ((fd
= _open_dev_node(dev_name
)) < 0)
1109 if (ioctl(fd
, BLKRASET
, read_ahead_long
)) {
1110 log_sys_error("BLKRASET", dev_name
);
1115 log_sys_debug("close", dev_name
);
1120 static int _set_dev_node_read_ahead(const char *dev_name
,
1121 uint32_t major
, uint32_t minor
,
1122 uint32_t read_ahead
, uint32_t read_ahead_flags
)
1124 uint32_t current_read_ahead
;
1126 if (read_ahead
== DM_READ_AHEAD_AUTO
)
1129 if (read_ahead
== DM_READ_AHEAD_NONE
)
1132 if (read_ahead_flags
& DM_READ_AHEAD_MINIMUM_FLAG
) {
1133 if (!get_dev_node_read_ahead(dev_name
, major
, minor
, ¤t_read_ahead
))
1136 if (current_read_ahead
> read_ahead
) {
1137 log_debug("%s: retaining kernel read ahead of %" PRIu32
1138 " (requested %" PRIu32
")",
1139 dev_name
, current_read_ahead
, read_ahead
);
1144 return _set_read_ahead(dev_name
, major
, minor
, read_ahead
);
1149 int get_dev_node_read_ahead(const char *dev_name
, uint32_t *read_ahead
)
1156 static int _set_dev_node_read_ahead(const char *dev_name
,
1157 uint32_t major
, uint32_t minor
,
1158 uint32_t read_ahead
, uint32_t read_ahead_flags
)
1172 static int _do_node_op(node_op_t type
, const char *dev_name
, uint32_t major
,
1173 uint32_t minor
, uid_t uid
, gid_t gid
, mode_t mode
,
1174 const char *old_name
, uint32_t read_ahead
,
1175 uint32_t read_ahead_flags
, int warn_if_udev_failed
)
1179 return _add_dev_node(dev_name
, major
, minor
, uid
, gid
,
1180 mode
, warn_if_udev_failed
);
1182 return _rm_dev_node(dev_name
, warn_if_udev_failed
);
1184 return _rename_dev_node(old_name
, dev_name
, warn_if_udev_failed
);
1185 case NODE_READ_AHEAD
:
1186 return _set_dev_node_read_ahead(dev_name
, major
, minor
,
1187 read_ahead
, read_ahead_flags
);
1195 static DM_LIST_INIT(_node_ops
);
1196 static int _count_node_ops
[NUM_NODES
];
1198 struct node_op_parms
{
1199 struct dm_list list
;
1207 uint32_t read_ahead
;
1208 uint32_t read_ahead_flags
;
1210 int warn_if_udev_failed
;
1211 unsigned rely_on_udev
;
1215 static void _store_str(char **pos
, char **ptr
, const char *str
)
1219 *pos
+= strlen(*ptr
) + 1;
1222 static void _del_node_op(struct node_op_parms
*nop
)
1224 _count_node_ops
[nop
->type
]--;
1225 dm_list_del(&nop
->list
);
1230 /* Check if there is other the type of node operation stacked */
1231 static int _other_node_ops(node_op_t type
)
1235 for (i
= 0; i
< NUM_NODES
; i
++)
1236 if (type
!= i
&& _count_node_ops
[i
])
1241 static void _log_node_op(const char *action_str
, struct node_op_parms
*nop
)
1243 const char *rely
= nop
->rely_on_udev
? " [trust_udev]" : "" ;
1244 const char *verify
= nop
->warn_if_udev_failed
? " [verify_udev]" : "";
1246 switch (nop
->type
) {
1248 log_debug("%s: %s NODE_ADD (%" PRIu32
",%" PRIu32
") %u:%u 0%o%s%s",
1249 nop
->dev_name
, action_str
, nop
->major
, nop
->minor
, nop
->uid
, nop
->gid
, nop
->mode
,
1253 log_debug("%s: %s NODE_DEL%s%s", nop
->dev_name
, action_str
, rely
, verify
);
1256 log_debug("%s: %s NODE_RENAME to %s%s%s", nop
->old_name
, action_str
, nop
->dev_name
, rely
, verify
);
1258 case NODE_READ_AHEAD
:
1259 log_debug("%s: %s NODE_READ_AHEAD %" PRIu32
" (flags=%" PRIu32
")%s%s",
1260 nop
->dev_name
, action_str
, nop
->read_ahead
, nop
->read_ahead_flags
, rely
, verify
);
1267 static int _stack_node_op(node_op_t type
, const char *dev_name
, uint32_t major
,
1268 uint32_t minor
, uid_t uid
, gid_t gid
, mode_t mode
,
1269 const char *old_name
, uint32_t read_ahead
,
1270 uint32_t read_ahead_flags
, int warn_if_udev_failed
,
1271 unsigned rely_on_udev
)
1273 struct node_op_parms
*nop
;
1274 struct dm_list
*noph
, *nopht
;
1275 size_t len
= strlen(dev_name
) + strlen(old_name
) + 2;
1279 * Note: warn_if_udev_failed must have valid content
1281 if ((type
== NODE_DEL
) && _other_node_ops(type
))
1283 * Ignore any outstanding operations on the node if deleting it.
1285 dm_list_iterate_safe(noph
, nopht
, &_node_ops
) {
1286 nop
= dm_list_item(noph
, struct node_op_parms
);
1287 if (!strcmp(dev_name
, nop
->dev_name
)) {
1288 _log_node_op("Unstacking", nop
);
1290 if (!_other_node_ops(type
))
1291 break; /* no other non DEL ops */
1294 else if ((type
== NODE_ADD
) && _count_node_ops
[NODE_DEL
])
1296 * Ignore previous DEL operation on added node.
1297 * (No other operations for this device then DEL could be stacked here).
1299 dm_list_iterate_safe(noph
, nopht
, &_node_ops
) {
1300 nop
= dm_list_item(noph
, struct node_op_parms
);
1301 if ((nop
->type
== NODE_DEL
) &&
1302 !strcmp(dev_name
, nop
->dev_name
)) {
1303 _log_node_op("Unstacking", nop
);
1305 break; /* no other DEL ops */
1308 else if (type
== NODE_RENAME
)
1310 * Ignore any outstanding operations if renaming it.
1312 * Currently RENAME operation happens through 'suspend -> resume'.
1313 * On 'resume' device is added with read_ahead settings, so it is
1314 * safe to remove any stacked ADD, RENAME, READ_AHEAD operation
1315 * There cannot be any DEL operation on the renamed device.
1317 dm_list_iterate_safe(noph
, nopht
, &_node_ops
) {
1318 nop
= dm_list_item(noph
, struct node_op_parms
);
1319 if (!strcmp(old_name
, nop
->dev_name
)) {
1320 _log_node_op("Unstacking", nop
);
1324 else if (type
== NODE_READ_AHEAD
) {
1325 /* udev doesn't process readahead */
1327 warn_if_udev_failed
= 0;
1330 if (!(nop
= dm_malloc(sizeof(*nop
) + len
))) {
1331 log_error("Insufficient memory to stack mknod operation");
1342 nop
->read_ahead
= read_ahead
;
1343 nop
->read_ahead_flags
= read_ahead_flags
;
1344 nop
->rely_on_udev
= rely_on_udev
;
1347 * Clear warn_if_udev_failed if rely_on_udev is set. It doesn't get
1348 * checked in this case - this just removes the flag from log messages.
1350 nop
->warn_if_udev_failed
= rely_on_udev
? 0 : warn_if_udev_failed
;
1352 _store_str(&pos
, &nop
->dev_name
, dev_name
);
1353 _store_str(&pos
, &nop
->old_name
, old_name
);
1355 _count_node_ops
[type
]++;
1356 dm_list_add(&_node_ops
, &nop
->list
);
1358 _log_node_op("Stacking", nop
);
1363 static void _pop_node_ops(void)
1365 struct dm_list
*noph
, *nopht
;
1366 struct node_op_parms
*nop
;
1368 dm_list_iterate_safe(noph
, nopht
, &_node_ops
) {
1369 nop
= dm_list_item(noph
, struct node_op_parms
);
1370 if (!nop
->rely_on_udev
) {
1371 _log_node_op("Processing", nop
);
1372 _do_node_op(nop
->type
, nop
->dev_name
, nop
->major
, nop
->minor
,
1373 nop
->uid
, nop
->gid
, nop
->mode
, nop
->old_name
,
1374 nop
->read_ahead
, nop
->read_ahead_flags
,
1375 nop
->warn_if_udev_failed
);
1377 _log_node_op("Skipping", nop
);
1382 int add_dev_node(const char *dev_name
, uint32_t major
, uint32_t minor
,
1383 uid_t uid
, gid_t gid
, mode_t mode
, int check_udev
, unsigned rely_on_udev
)
1385 return _stack_node_op(NODE_ADD
, dev_name
, major
, minor
, uid
,
1386 gid
, mode
, "", 0, 0, check_udev
, rely_on_udev
);
1389 int rename_dev_node(const char *old_name
, const char *new_name
, int check_udev
, unsigned rely_on_udev
)
1391 return _stack_node_op(NODE_RENAME
, new_name
, 0, 0, 0,
1392 0, 0, old_name
, 0, 0, check_udev
, rely_on_udev
);
1395 int rm_dev_node(const char *dev_name
, int check_udev
, unsigned rely_on_udev
)
1397 return _stack_node_op(NODE_DEL
, dev_name
, 0, 0, 0,
1398 0, 0, "", 0, 0, check_udev
, rely_on_udev
);
1401 int set_dev_node_read_ahead(const char *dev_name
,
1402 uint32_t major
, uint32_t minor
,
1403 uint32_t read_ahead
, uint32_t read_ahead_flags
)
1405 if (read_ahead
== DM_READ_AHEAD_AUTO
)
1408 return _stack_node_op(NODE_READ_AHEAD
, dev_name
, major
, minor
, 0, 0,
1409 0, "", read_ahead
, read_ahead_flags
, 0, 0);
1412 void update_devs(void)
1417 static int _canonicalize_and_set_dir(const char *src
, const char *suffix
, size_t max_len
, char *dir
)
1423 log_debug("Invalid directory value, %s: "
1424 "not an absolute name.", src
);
1429 slash
= src
[len
-1] == '/' ? "" : "/";
1431 if (dm_snprintf(dir
, max_len
, "%s%s%s", src
, slash
, suffix
? suffix
: "") < 0) {
1432 log_debug("Invalid directory value, %s: name too long.", src
);
1439 int dm_set_dev_dir(const char *dev_dir
)
1441 return _canonicalize_and_set_dir(dev_dir
, DM_DIR
, sizeof _dm_dir
, _dm_dir
);
1444 const char *dm_dir(void)
1449 int dm_set_sysfs_dir(const char *sysfs_dir
)
1451 if (!sysfs_dir
|| !*sysfs_dir
) {
1452 _sysfs_dir
[0] = '\0';
1456 return _canonicalize_and_set_dir(sysfs_dir
, NULL
, sizeof _sysfs_dir
, _sysfs_dir
);
1459 const char *dm_sysfs_dir(void)
1465 * Replace existing uuid_prefix provided it isn't too long.
1467 int dm_set_uuid_prefix(const char *uuid_prefix
)
1472 if (strlen(uuid_prefix
) > DM_MAX_UUID_PREFIX_LEN
) {
1473 log_error("New uuid prefix %s too long.", uuid_prefix
);
1477 strcpy(_default_uuid_prefix
, uuid_prefix
);
1482 const char *dm_uuid_prefix(void)
1484 return _default_uuid_prefix
;
1487 static int _sysfs_get_dm_name(uint32_t major
, uint32_t minor
, char *buf
, size_t buf_size
)
1489 char *sysfs_path
, *temp_buf
= NULL
;
1494 if (!(sysfs_path
= dm_malloc(PATH_MAX
)) ||
1495 !(temp_buf
= dm_malloc(PATH_MAX
))) {
1496 log_error("_sysfs_get_dm_name: failed to allocate temporary buffers");
1500 if (dm_snprintf(sysfs_path
, PATH_MAX
, "%sdev/block/%" PRIu32
":%" PRIu32
1501 "/dm/name", _sysfs_dir
, major
, minor
) < 0) {
1502 log_error("_sysfs_get_dm_name: dm_snprintf failed");
1506 if (!(fp
= fopen(sysfs_path
, "r"))) {
1507 if (errno
!= ENOENT
)
1508 log_sys_error("fopen", sysfs_path
);
1510 log_sys_debug("fopen", sysfs_path
);
1514 if (!fgets(temp_buf
, PATH_MAX
, fp
)) {
1515 log_sys_error("fgets", sysfs_path
);
1519 len
= strlen(temp_buf
);
1521 if (len
> buf_size
) {
1522 log_error("_sysfs_get_dm_name: supplied buffer too small");
1526 temp_buf
[len
? len
- 1 : 0] = '\0'; /* \n */
1527 strcpy(buf
, temp_buf
);
1530 if (fp
&& fclose(fp
))
1531 log_sys_error("fclose", sysfs_path
);
1534 dm_free(sysfs_path
);
1539 static int _sysfs_get_kernel_name(uint32_t major
, uint32_t minor
, char *buf
, size_t buf_size
)
1541 char *name
, *sysfs_path
, *temp_buf
= NULL
;
1546 if (!(sysfs_path
= dm_malloc(PATH_MAX
)) ||
1547 !(temp_buf
= dm_malloc(PATH_MAX
))) {
1548 log_error("_sysfs_get_kernel_name: failed to allocate temporary buffers");
1552 if (dm_snprintf(sysfs_path
, PATH_MAX
, "%sdev/block/%" PRIu32
":%" PRIu32
,
1553 _sysfs_dir
, major
, minor
) < 0) {
1554 log_error("_sysfs_get_kernel_name: dm_snprintf failed");
1558 if ((size
= readlink(sysfs_path
, temp_buf
, PATH_MAX
- 1)) < 0) {
1559 if (errno
!= ENOENT
)
1560 log_sys_error("readlink", sysfs_path
);
1562 log_sys_debug("readlink", sysfs_path
);
1565 temp_buf
[size
] = '\0';
1567 if (!(name
= strrchr(temp_buf
, '/'))) {
1568 log_error("Could not locate device kernel name in sysfs path %s", temp_buf
);
1572 len
= size
- (name
- temp_buf
) + 1;
1574 if (len
> buf_size
) {
1575 log_error("_sysfs_get_kernel_name: output buffer too small");
1583 dm_free(sysfs_path
);
1588 int dm_device_get_name(uint32_t major
, uint32_t minor
, int prefer_kernel_name
,
1589 char *buf
, size_t buf_size
)
1595 * device-mapper devices and prefer_kernel_name = 0
1596 * get dm name by reading /sys/dev/block/major:minor/dm/name,
1597 * fallback to _sysfs_get_kernel_name if not successful
1599 if (dm_is_dm_major(major
) && !prefer_kernel_name
) {
1600 if (_sysfs_get_dm_name(major
, minor
, buf
, buf_size
))
1607 * non-device-mapper devices or prefer_kernel_name = 1
1608 * get kernel name using readlink /sys/dev/block/major:minor -> .../dm-X
1610 return _sysfs_get_kernel_name(major
, minor
, buf
, buf_size
);
1613 int dm_device_has_holders(uint32_t major
, uint32_t minor
)
1615 char sysfs_path
[PATH_MAX
];
1621 if (dm_snprintf(sysfs_path
, PATH_MAX
, "%sdev/block/%" PRIu32
1622 ":%" PRIu32
"/holders", _sysfs_dir
, major
, minor
) < 0) {
1623 log_error("sysfs_path dm_snprintf failed");
1627 if (stat(sysfs_path
, &st
)) {
1628 log_sys_error("stat", sysfs_path
);
1632 return !dm_is_empty_dir(sysfs_path
);
1635 static int _mounted_fs_on_device(const char *kernel_dev_name
)
1637 char sysfs_path
[PATH_MAX
];
1638 struct dirent
*dirent
;
1643 if (dm_snprintf(sysfs_path
, PATH_MAX
, "%sfs", _sysfs_dir
) < 0) {
1644 log_error("sysfs_path dm_snprintf failed");
1648 if (!(d
= opendir(sysfs_path
))) {
1649 if (errno
!= ENOENT
)
1650 log_sys_error("opendir", sysfs_path
);
1654 while ((dirent
= readdir(d
))) {
1655 if (!strcmp(dirent
->d_name
, ".") || !strcmp(dirent
->d_name
, ".."))
1658 if (dm_snprintf(sysfs_path
, PATH_MAX
, "%sfs/%s/%s",
1659 _sysfs_dir
, dirent
->d_name
, kernel_dev_name
) < 0) {
1660 log_error("sysfs_path dm_snprintf failed");
1664 if (!stat(sysfs_path
, &st
)) {
1669 else if (errno
!= ENOENT
) {
1670 log_sys_error("stat", sysfs_path
);
1676 log_error("_fs_present_on_device: %s: closedir failed", kernel_dev_name
);
1681 int dm_device_has_mounted_fs(uint32_t major
, uint32_t minor
)
1683 char kernel_dev_name
[PATH_MAX
];
1685 /* Get kernel device name first */
1686 if (!dm_device_get_name(major
, minor
, 1, kernel_dev_name
, PATH_MAX
))
1689 /* Check /sys/fs/<fs_name>/<kernel_dev_name> presence */
1690 return _mounted_fs_on_device(kernel_dev_name
);
1693 int dm_mknodes(const char *name
)
1695 struct dm_task
*dmt
;
1698 if (!(dmt
= dm_task_create(DM_DEVICE_MKNODES
)))
1701 if (name
&& !dm_task_set_name(dmt
, name
))
1704 if (!dm_task_no_open_count(dmt
))
1707 r
= dm_task_run(dmt
);
1710 dm_task_destroy(dmt
);
1714 int dm_driver_version(char *version
, size_t size
)
1716 struct dm_task
*dmt
;
1719 if (!(dmt
= dm_task_create(DM_DEVICE_VERSION
)))
1722 if (!dm_task_run(dmt
))
1723 log_error("Failed to get driver version");
1725 if (!dm_task_get_driver_version(dmt
, version
, size
))
1731 dm_task_destroy(dmt
);
1735 #ifndef UDEV_SYNC_SUPPORT
1736 void dm_udev_set_sync_support(int sync_with_udev
)
1740 int dm_udev_get_sync_support(void)
1745 void dm_udev_set_checking(int checking
)
1749 int dm_udev_get_checking(void)
1754 int dm_task_set_cookie(struct dm_task
*dmt
, uint32_t *cookie
, uint16_t flags
)
1756 if (dm_cookie_supported())
1757 dmt
->event_nr
= flags
<< DM_UDEV_FLAGS_SHIFT
;
1763 int dm_udev_complete(uint32_t cookie
)
1768 int dm_udev_wait(uint32_t cookie
)
1775 #else /* UDEV_SYNC_SUPPORT */
1777 static int _check_semaphore_is_supported(void)
1781 struct seminfo seminfo
;
1783 arg
.__buf
= &seminfo
;
1784 maxid
= semctl(0, 0, SEM_INFO
, arg
);
1787 log_warn("Kernel not configured for semaphores (System V IPC). "
1788 "Not using udev synchronisation code.");
1795 static int _check_udev_is_running(void)
1798 struct udev_queue
*udev_queue
;
1801 if (!(udev
= udev_new()))
1804 if (!(udev_queue
= udev_queue_new(udev
))) {
1809 if (!(r
= udev_queue_get_udev_is_active(udev_queue
)))
1810 log_debug("Udev is not running. "
1811 "Not using udev synchronisation code.");
1813 udev_queue_unref(udev_queue
);
1819 log_error("Could not get udev state. Assuming udev is not running.");
1823 static void _check_udev_sync_requirements_once(void)
1825 if (_semaphore_supported
< 0)
1826 _semaphore_supported
= _check_semaphore_is_supported();
1828 if (_udev_running
< 0)
1829 _udev_running
= _check_udev_is_running();
1832 void dm_udev_set_sync_support(int sync_with_udev
)
1834 _check_udev_sync_requirements_once();
1835 _sync_with_udev
= sync_with_udev
;
1838 int dm_udev_get_sync_support(void)
1840 _check_udev_sync_requirements_once();
1842 return _semaphore_supported
&& dm_cookie_supported() &&
1843 _udev_running
&& _sync_with_udev
;
1846 void dm_udev_set_checking(int checking
)
1848 if ((_udev_checking
= checking
))
1849 log_debug("DM udev checking enabled");
1851 log_debug("DM udev checking disabled");
1854 int dm_udev_get_checking(void)
1856 return _udev_checking
;
1859 static int _get_cookie_sem(uint32_t cookie
, int *semid
)
1861 if (cookie
>> 16 != DM_COOKIE_MAGIC
) {
1862 log_error("Could not continue to access notification "
1863 "semaphore identified by cookie value %"
1864 PRIu32
" (0x%x). Incorrect cookie prefix.",
1869 if ((*semid
= semget((key_t
) cookie
, 1, 0)) >= 0)
1874 log_error("Could not find notification "
1875 "semaphore identified by cookie "
1876 "value %" PRIu32
" (0x%x)",
1880 log_error("No permission to access "
1881 "notificaton semaphore identified "
1882 "by cookie value %" PRIu32
" (0x%x)",
1886 log_error("Failed to access notification "
1887 "semaphore identified by cookie "
1888 "value %" PRIu32
" (0x%x): %s",
1889 cookie
, cookie
, strerror(errno
));
1896 static int _udev_notify_sem_inc(uint32_t cookie
, int semid
)
1898 struct sembuf sb
= {0, 1, 0};
1901 if (semop(semid
, &sb
, 1) < 0) {
1902 log_error("semid %d: semop failed for cookie 0x%" PRIx32
": %s",
1903 semid
, cookie
, strerror(errno
));
1907 if ((val
= semctl(semid
, 0, GETVAL
)) < 0) {
1908 log_error("semid %d: sem_ctl GETVAL failed for "
1909 "cookie 0x%" PRIx32
": %s",
1910 semid
, cookie
, strerror(errno
));
1914 log_debug("Udev cookie 0x%" PRIx32
" (semid %d) incremented to %d",
1915 cookie
, semid
, val
);
1920 static int _udev_notify_sem_dec(uint32_t cookie
, int semid
)
1922 struct sembuf sb
= {0, -1, IPC_NOWAIT
};
1925 if ((val
= semctl(semid
, 0, GETVAL
)) < 0) {
1926 log_error("semid %d: sem_ctl GETVAL failed for "
1927 "cookie 0x%" PRIx32
": %s",
1928 semid
, cookie
, strerror(errno
));
1932 if (semop(semid
, &sb
, 1) < 0) {
1935 log_error("semid %d: semop failed for cookie "
1937 "incorrect semaphore state",
1941 log_error("semid %d: semop failed for cookie "
1942 "0x%" PRIx32
": %s",
1943 semid
, cookie
, strerror(errno
));
1949 log_debug("Udev cookie 0x%" PRIx32
" (semid %d) decremented to %d",
1950 cookie
, semid
, val
- 1);
1955 static int _udev_notify_sem_destroy(uint32_t cookie
, int semid
)
1957 if (semctl(semid
, 0, IPC_RMID
, 0) < 0) {
1958 log_error("Could not cleanup notification semaphore "
1959 "identified by cookie value %" PRIu32
" (0x%x): %s",
1960 cookie
, cookie
, strerror(errno
));
1964 log_debug("Udev cookie 0x%" PRIx32
" (semid %d) destroyed", cookie
,
1970 static int _udev_notify_sem_create(uint32_t *cookie
, int *semid
)
1975 uint16_t base_cookie
;
1976 uint32_t gen_cookie
;
1977 union semun sem_arg
;
1979 if ((fd
= open("/dev/urandom", O_RDONLY
)) < 0) {
1980 log_error("Failed to open /dev/urandom "
1981 "to create random cookie value");
1986 /* Generate random cookie value. Be sure it is unique and non-zero. */
1988 /* FIXME Handle non-error returns from read(). Move _io() into libdm? */
1989 if (read(fd
, &base_cookie
, sizeof(base_cookie
)) != sizeof(base_cookie
)) {
1990 log_error("Failed to initialize notification cookie");
1994 gen_cookie
= DM_COOKIE_MAGIC
<< 16 | base_cookie
;
1996 if (base_cookie
&& (gen_semid
= semget((key_t
) gen_cookie
,
1997 1, 0600 | IPC_CREAT
| IPC_EXCL
)) < 0) {
2000 /* if the semaphore key exists, we
2001 * simply generate another random one */
2005 log_error("Not enough memory to create "
2006 "notification semaphore");
2009 log_error("Limit for the maximum number "
2010 "of semaphores reached. You can "
2011 "check and set the limits in "
2012 "/proc/sys/kernel/sem.");
2015 log_error("Failed to create notification "
2016 "semaphore: %s", strerror(errno
));
2020 } while (!base_cookie
);
2022 log_debug("Udev cookie 0x%" PRIx32
" (semid %d) created",
2023 gen_cookie
, gen_semid
);
2027 if (semctl(gen_semid
, 0, SETVAL
, sem_arg
) < 0) {
2028 log_error("semid %d: semctl failed: %s", gen_semid
, strerror(errno
));
2029 /* We have to destroy just created semaphore
2030 * so it won't stay in the system. */
2031 (void) _udev_notify_sem_destroy(gen_cookie
, gen_semid
);
2035 if ((val
= semctl(gen_semid
, 0, GETVAL
)) < 0) {
2036 log_error("semid %d: sem_ctl GETVAL failed for "
2037 "cookie 0x%" PRIx32
": %s",
2038 gen_semid
, gen_cookie
, strerror(errno
));
2042 log_debug("Udev cookie 0x%" PRIx32
" (semid %d) incremented to %d",
2043 gen_cookie
, gen_semid
, val
);
2049 *cookie
= gen_cookie
;
2062 int dm_udev_create_cookie(uint32_t *cookie
)
2066 if (!dm_udev_get_sync_support()) {
2071 return _udev_notify_sem_create(cookie
, &semid
);
2074 static const char *_task_type_disp(int type
)
2077 case DM_DEVICE_CREATE
:
2079 case DM_DEVICE_RELOAD
:
2081 case DM_DEVICE_REMOVE
:
2083 case DM_DEVICE_REMOVE_ALL
:
2084 return "REMOVE_ALL";
2085 case DM_DEVICE_SUSPEND
:
2087 case DM_DEVICE_RESUME
:
2089 case DM_DEVICE_INFO
:
2091 case DM_DEVICE_DEPS
:
2093 case DM_DEVICE_RENAME
:
2095 case DM_DEVICE_VERSION
:
2097 case DM_DEVICE_STATUS
:
2099 case DM_DEVICE_TABLE
:
2101 case DM_DEVICE_WAITEVENT
:
2103 case DM_DEVICE_LIST
:
2105 case DM_DEVICE_CLEAR
:
2107 case DM_DEVICE_MKNODES
:
2109 case DM_DEVICE_LIST_VERSIONS
:
2110 return "LIST_VERSIONS";
2111 case DM_DEVICE_TARGET_MSG
:
2112 return "TARGET_MSG";
2113 case DM_DEVICE_SET_GEOMETRY
:
2114 return "SET_GEOMETRY";
2119 int dm_task_set_cookie(struct dm_task
*dmt
, uint32_t *cookie
, uint16_t flags
)
2123 if (dm_cookie_supported())
2124 dmt
->event_nr
= flags
<< DM_UDEV_FLAGS_SHIFT
;
2126 if (!dm_udev_get_sync_support()) {
2132 if (!_get_cookie_sem(*cookie
, &semid
))
2134 } else if (!_udev_notify_sem_create(cookie
, &semid
))
2137 if (!_udev_notify_sem_inc(*cookie
, semid
)) {
2138 log_error("Could not set notification semaphore "
2139 "identified by cookie value %" PRIu32
" (0x%x)",
2144 dmt
->event_nr
|= ~DM_UDEV_FLAGS_MASK
& *cookie
;
2145 dmt
->cookie_set
= 1;
2147 log_debug("Udev cookie 0x%" PRIx32
" (semid %d) assigned to "
2148 "%s task(%d) with flags%s%s%s%s%s%s%s (0x%" PRIx16
")", *cookie
, semid
, _task_type_disp(dmt
->type
), dmt
->type
,
2149 (flags
& DM_UDEV_DISABLE_DM_RULES_FLAG
) ? " DISABLE_DM_RULES" : "",
2150 (flags
& DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG
) ? " DISABLE_SUBSYSTEM_RULES" : "",
2151 (flags
& DM_UDEV_DISABLE_DISK_RULES_FLAG
) ? " DISABLE_DISK_RULES" : "",
2152 (flags
& DM_UDEV_DISABLE_OTHER_RULES_FLAG
) ? " DISABLE_OTHER_RULES" : "",
2153 (flags
& DM_UDEV_LOW_PRIORITY_FLAG
) ? " LOW_PRIORITY" : "",
2154 (flags
& DM_UDEV_DISABLE_LIBRARY_FALLBACK
) ? " DISABLE_LIBRARY_FALLBACK" : "",
2155 (flags
& DM_UDEV_PRIMARY_SOURCE_FLAG
) ? " PRIMARY_SOURCE" : "",
2165 int dm_udev_complete(uint32_t cookie
)
2169 if (!cookie
|| !dm_udev_get_sync_support())
2172 if (!_get_cookie_sem(cookie
, &semid
))
2175 if (!_udev_notify_sem_dec(cookie
, semid
)) {
2176 log_error("Could not signal waiting process using notification "
2177 "semaphore identified by cookie value %" PRIu32
" (0x%x)",
2185 static int _udev_wait(uint32_t cookie
)
2188 struct sembuf sb
= {0, 0, 0};
2190 if (!cookie
|| !dm_udev_get_sync_support())
2193 if (!_get_cookie_sem(cookie
, &semid
))
2196 if (!_udev_notify_sem_dec(cookie
, semid
)) {
2197 log_error("Failed to set a proper state for notification "
2198 "semaphore identified by cookie value %" PRIu32
" (0x%x) "
2199 "to initialize waiting for incoming notifications.",
2201 (void) _udev_notify_sem_destroy(cookie
, semid
);
2205 log_debug("Udev cookie 0x%" PRIx32
" (semid %d) waiting for zero",
2209 if (semop(semid
, &sb
, 1) < 0) {
2212 else if (errno
== EIDRM
)
2215 log_error("Could not set wait state for notification semaphore "
2216 "identified by cookie value %" PRIu32
" (0x%x): %s",
2217 cookie
, cookie
, strerror(errno
));
2218 (void) _udev_notify_sem_destroy(cookie
, semid
);
2222 return _udev_notify_sem_destroy(cookie
, semid
);
2225 int dm_udev_wait(uint32_t cookie
)
2227 int r
= _udev_wait(cookie
);
2234 #endif /* UDEV_SYNC_SUPPORT */