summaryrefslogtreecommitdiff
path: root/lib/misc
diff options
context:
space:
mode:
authorKarol Lewandowski <k.lewandowsk@samsung.com>2024-01-23 12:58:00 +0100
committerKarol Lewandowski <k.lewandowsk@samsung.com>2024-01-23 12:58:00 +0100
commitcbab226a74fbaaa43220dee80e8435555c6506ce (patch)
tree1bbd14ec625ea85d0bcc32232d51c1f71e2604d2 /lib/misc
parent44a3c2255bc480c82f34db156553a595606d8a0b (diff)
downloaddevice-mapper-sandbox/klewandowski/upstream_2.03.22.tar.gz
device-mapper-sandbox/klewandowski/upstream_2.03.22.tar.bz2
device-mapper-sandbox/klewandowski/upstream_2.03.22.zip
Diffstat (limited to 'lib/misc')
-rw-r--r--lib/misc/configure.h.in645
-rw-r--r--lib/misc/crc.c10
-rw-r--r--lib/misc/crc.h4
-rw-r--r--lib/misc/crc_gen.c4
-rw-r--r--lib/misc/intl.h2
-rw-r--r--lib/misc/last-path-component.h2
-rw-r--r--lib/misc/lib.h30
-rw-r--r--lib/misc/lvm-exec.c167
-rw-r--r--lib/misc/lvm-exec.h40
-rw-r--r--lib/misc/lvm-file.c83
-rw-r--r--lib/misc/lvm-file.h24
-rw-r--r--lib/misc/lvm-flock.c256
-rw-r--r--lib/misc/lvm-flock.h22
-rw-r--r--lib/misc/lvm-globals.c218
-rw-r--r--lib/misc/lvm-globals.h42
-rw-r--r--lib/misc/lvm-maths.c38
-rw-r--r--lib/misc/lvm-maths.h24
-rw-r--r--lib/misc/lvm-percent.c30
-rw-r--r--lib/misc/lvm-percent.h38
-rw-r--r--lib/misc/lvm-signal.c190
-rw-r--r--lib/misc/lvm-signal.h34
-rw-r--r--lib/misc/lvm-string.c256
-rw-r--r--lib/misc/lvm-string.h35
-rw-r--r--lib/misc/lvm-version.h.in30
-rw-r--r--lib/misc/lvm-wrappers.c73
-rw-r--r--lib/misc/lvm-wrappers.h30
-rw-r--r--lib/misc/sharedlib.c47
-rw-r--r--lib/misc/sharedlib.h7
-rw-r--r--lib/misc/timestamp.c129
-rw-r--r--lib/misc/timestamp.h33
-rw-r--r--lib/misc/util.h107
31 files changed, 1456 insertions, 1194 deletions
diff --git a/lib/misc/configure.h.in b/lib/misc/configure.h.in
deleted file mode 100644
index fdc5a26..0000000
--- a/lib/misc/configure.h.in
+++ /dev/null
@@ -1,645 +0,0 @@
-/* lib/misc/configure.h.in. Generated from configure.in by autoheader. */
-
-/* Define to 1 if the `closedir' function returns void instead of `int'. */
-#undef CLOSEDIR_VOID
-
-/* Define to 1 to include built-in support for clustered LVM locking. */
-#undef CLUSTER_LOCKING_INTERNAL
-
-/* Path to clvmd binary. */
-#undef CLVMD_PATH
-
-/* Path to clvmd pidfile. */
-#undef CLVMD_PIDFILE
-
-/* Path to cmirrord pidfile. */
-#undef CMIRRORD_PIDFILE
-
-/* Define to 0 to exclude libSaCkpt. */
-#undef CMIRROR_HAS_CHECKPOINT
-
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
- systems. This function is required for `alloca.c' support on those systems.
- */
-#undef CRAY_STACKSEG_END
-
-/* Define to 1 if using `alloca.c'. */
-#undef C_ALLOCA
-
-/* Name of default metadata archive subdirectory. */
-#undef DEFAULT_ARCHIVE_SUBDIR
-
-/* Name of default metadata backup subdirectory. */
-#undef DEFAULT_BACKUP_SUBDIR
-
-/* Name of default metadata cache subdirectory. */
-#undef DEFAULT_CACHE_SUBDIR
-
-/* Default data alignment. */
-#undef DEFAULT_DATA_ALIGNMENT
-
-/* Define default node creation behavior with dmsetup create */
-#undef DEFAULT_DM_ADD_NODE
-
-/* Define default name mangling behaviour */
-#undef DEFAULT_DM_NAME_MANGLING
-
-/* Default DM run directory. */
-#undef DEFAULT_DM_RUN_DIR
-
-/* Name of default locking directory. */
-#undef DEFAULT_LOCK_DIR
-
-/* Default directory to keep PID files in. */
-#undef DEFAULT_PID_DIR
-
-/* Default LVM run directory. */
-#undef DEFAULT_RUN_DIR
-
-/* Define to 0 to reinstate the pre-2.02.54 handling of unit suffixes. */
-#undef DEFAULT_SI_UNIT_CONSISTENCY
-
-/* Path to LVM system directory. */
-#undef DEFAULT_SYS_DIR
-
-/* Define to 1 to enable LVM2 device-mapper interaction. */
-#undef DEVMAPPER_SUPPORT
-
-/* Define to 1 to enable the device-mapper event daemon. */
-#undef DMEVENTD
-
-/* Path to dmeventd binary. */
-#undef DMEVENTD_PATH
-
-/* Path to dmeventd pidfile. */
-#undef DMEVENTD_PIDFILE
-
-/* Library version */
-#undef DM_LIB_VERSION
-
-/* Define to 1 if you have `alloca', as a function or macro. */
-#undef HAVE_ALLOCA
-
-/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
- */
-#undef HAVE_ALLOCA_H
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#undef HAVE_ARPA_INET_H
-
-/* Define to 1 if you have the <asm/byteorder.h> header file. */
-#undef HAVE_ASM_BYTEORDER_H
-
-/* Define to 1 if you have the <assert.h> header file. */
-#undef HAVE_ASSERT_H
-
-/* Define to 1 if canonicalize_file_name is available. */
-#undef HAVE_CANONICALIZE_FILE_NAME
-
-/* Define to 1 if your system has a working `chown' function. */
-#undef HAVE_CHOWN
-
-/* Define to 1 if you have the <corosync/cmap.h> header file. */
-#undef HAVE_COROSYNC_CMAP_H
-
-/* Define to 1 if you have the <corosync/confdb.h> header file. */
-#undef HAVE_COROSYNC_CONFDB_H
-
-/* Define to 1 if you have the <ctype.h> header file. */
-#undef HAVE_CTYPE_H
-
-/* Define to 1 if you have the <dirent.h> header file. */
-#undef HAVE_DIRENT_H
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-#undef HAVE_DOPRNT
-
-/* Define to 1 if you have the `dup2' function. */
-#undef HAVE_DUP2
-
-/* Define to 1 if you have the <errno.h> header file. */
-#undef HAVE_ERRNO_H
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define to 1 if you have the `fork' function. */
-#undef HAVE_FORK
-
-/* Define to 1 if you have the `ftruncate' function. */
-#undef HAVE_FTRUNCATE
-
-/* Define to 1 if you have the `gethostname' function. */
-#undef HAVE_GETHOSTNAME
-
-/* Define to 1 if getline is available. */
-#undef HAVE_GETLINE
-
-/* Define to 1 if you have the `getmntent' function. */
-#undef HAVE_GETMNTENT
-
-/* Define to 1 if getopt_long is available. */
-#undef HAVE_GETOPTLONG
-
-/* Define to 1 if you have the <getopt.h> header file. */
-#undef HAVE_GETOPT_H
-
-/* Define to 1 if you have the `getpagesize' function. */
-#undef HAVE_GETPAGESIZE
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <langinfo.h> header file. */
-#undef HAVE_LANGINFO_H
-
-/* Define to 1 if you have the <libcman.h> header file. */
-#undef HAVE_LIBCMAN_H
-
-/* Define to 1 if dynamic libraries are available. */
-#undef HAVE_LIBDL
-
-/* Define to 1 if you have the <libdlm.h> header file. */
-#undef HAVE_LIBDLM_H
-
-/* Define to 1 if you have the <libgen.h> header file. */
-#undef HAVE_LIBGEN_H
-
-/* Define to 1 if you have the <libintl.h> header file. */
-#undef HAVE_LIBINTL_H
-
-/* Define to 1 if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
-
-/* Define to 1 if you have the <linux/fs.h> header file. */
-#undef HAVE_LINUX_FS_H
-
-/* Define to 1 if you have the <locale.h> header file. */
-#undef HAVE_LOCALE_H
-
-/* Define to 1 if `lstat' has the bug that it succeeds when given the
- zero-length file name argument. */
-#undef HAVE_LSTAT_EMPTY_STRING_BUG
-
-/* Define to 1 if you have the <machine/endian.h> header file. */
-#undef HAVE_MACHINE_ENDIAN_H
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
- to 0 otherwise. */
-#undef HAVE_MALLOC
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
-
-/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the `memset' function. */
-#undef HAVE_MEMSET
-
-/* Define to 1 if you have the `mkdir' function. */
-#undef HAVE_MKDIR
-
-/* Define to 1 if you have the `mkfifo' function. */
-#undef HAVE_MKFIFO
-
-/* Define to 1 if you have a working `mmap' system call. */
-#undef HAVE_MMAP
-
-/* Define to 1 if you have the <mntent.h> header file. */
-#undef HAVE_MNTENT_H
-
-/* Define to 1 if you have the `munmap' function. */
-#undef HAVE_MUNMAP
-
-/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
-#undef HAVE_NDIR_H
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#undef HAVE_NETDB_H
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#undef HAVE_NETINET_IN_H
-
-/* Define to 1 if you have the `nl_langinfo' function. */
-#undef HAVE_NL_LANGINFO
-
-/* Define to 1 if you have the <pthread.h> header file. */
-#undef HAVE_PTHREAD_H
-
-/* Define to 1 if you have the <readline/history.h> header file. */
-#undef HAVE_READLINE_HISTORY_H
-
-/* Define to 1 if you have the <readline/readline.h> header file. */
-#undef HAVE_READLINE_READLINE_H
-
-/* Define to 1 if your system has a GNU libc compatible `realloc' function,
- and to 0 otherwise. */
-#undef HAVE_REALLOC
-
-/* Define to 1 to include support for realtime clock. */
-#undef HAVE_REALTIME
-
-/* Define to 1 if you have the `rl_completion_matches' function. */
-#undef HAVE_RL_COMPLETION_MATCHES
-
-/* Define to 1 if you have the `rmdir' function. */
-#undef HAVE_RMDIR
-
-/* Define to 1 if you have the <search.h> header file. */
-#undef HAVE_SEARCH_H
-
-/* Define to 1 if you have the `select' function. */
-#undef HAVE_SELECT
-
-/* Define to 1 to include support for selinux. */
-#undef HAVE_SELINUX
-
-/* Define to 1 if you have the <selinux/label.h> header file. */
-#undef HAVE_SELINUX_LABEL_H
-
-/* Define to 1 if you have the <selinux/selinux.h> header file. */
-#undef HAVE_SELINUX_SELINUX_H
-
-/* Define to 1 if sepol_check_context is available. */
-#undef HAVE_SEPOL
-
-/* Define to 1 if you have the `setenv' function. */
-#undef HAVE_SETENV
-
-/* Define to 1 if you have the `setlocale' function. */
-#undef HAVE_SETLOCALE
-
-/* Define to 1 if you have the `siginterrupt' function. */
-#undef HAVE_SIGINTERRUPT
-
-/* Define to 1 if you have the <signal.h> header file. */
-#undef HAVE_SIGNAL_H
-
-/* Define to 1 if you have the `socket' function. */
-#undef HAVE_SOCKET
-
-/* Define to 1 if `stat' has the bug that it succeeds when given the
- zero-length file name argument. */
-#undef HAVE_STAT_EMPTY_STRING_BUG
-
-/* Define to 1 if you have the <stdarg.h> header file. */
-#undef HAVE_STDARG_H
-
-/* Define to 1 if you have the <stddef.h> header file. */
-#undef HAVE_STDDEF_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#undef HAVE_STDIO_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
-
-/* Define to 1 if you have the `strchr' function. */
-#undef HAVE_STRCHR
-
-/* Define to 1 if you have the `strcspn' function. */
-#undef HAVE_STRCSPN
-
-/* Define to 1 if you have the `strdup' function. */
-#undef HAVE_STRDUP
-
-/* Define to 1 if you have the `strerror' function. */
-#undef HAVE_STRERROR
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the `strncasecmp' function. */
-#undef HAVE_STRNCASECMP
-
-/* Define to 1 if you have the `strrchr' function. */
-#undef HAVE_STRRCHR
-
-/* Define to 1 if you have the `strspn' function. */
-#undef HAVE_STRSPN
-
-/* Define to 1 if you have the `strstr' function. */
-#undef HAVE_STRSTR
-
-/* Define to 1 if you have the `strtol' function. */
-#undef HAVE_STRTOL
-
-/* Define to 1 if you have the `strtoul' function. */
-#undef HAVE_STRTOUL
-
-/* Define to 1 if `st_rdev' is a member of `struct stat'. */
-#undef HAVE_STRUCT_STAT_ST_RDEV
-
-/* Define to 1 if you have the <syslog.h> header file. */
-#undef HAVE_SYSLOG_H
-
-/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
- */
-#undef HAVE_SYS_DIR_H
-
-/* Define to 1 if you have the <sys/disk.h> header file. */
-#undef HAVE_SYS_DISK_H
-
-/* Define to 1 if you have the <sys/file.h> header file. */
-#undef HAVE_SYS_FILE_H
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#undef HAVE_SYS_IOCTL_H
-
-/* Define to 1 if you have the <sys/ipc.h> header file. */
-#undef HAVE_SYS_IPC_H
-
-/* Define to 1 if you have the <sys/mman.h> header file. */
-#undef HAVE_SYS_MMAN_H
-
-/* Define to 1 if you have the <sys/mount.h> header file. */
-#undef HAVE_SYS_MOUNT_H
-
-/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
- */
-#undef HAVE_SYS_NDIR_H
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#undef HAVE_SYS_PARAM_H
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#undef HAVE_SYS_RESOURCE_H
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#undef HAVE_SYS_SELECT_H
-
-/* Define to 1 if you have the <sys/sem.h> header file. */
-#undef HAVE_SYS_SEM_H
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#undef HAVE_SYS_SOCKET_H
-
-/* Define to 1 if you have the <sys/statvfs.h> header file. */
-#undef HAVE_SYS_STATVFS_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <sys/uio.h> header file. */
-#undef HAVE_SYS_UIO_H
-
-/* Define to 1 if you have the <sys/un.h> header file. */
-#undef HAVE_SYS_UN_H
-
-/* Define to 1 if you have the <sys/utsname.h> header file. */
-#undef HAVE_SYS_UTSNAME_H
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define to 1 if you have the <termios.h> header file. */
-#undef HAVE_TERMIOS_H
-
-/* Define to 1 if you have the <time.h> header file. */
-#undef HAVE_TIME_H
-
-/* Define to 1 if you have the `uname' function. */
-#undef HAVE_UNAME
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the <utmpx.h> header file. */
-#undef HAVE_UTMPX_H
-
-/* Define to 1 if you have the `vfork' function. */
-#undef HAVE_VFORK
-
-/* Define to 1 if you have the <vfork.h> header file. */
-#undef HAVE_VFORK_H
-
-/* Define to 1 if you have the `vprintf' function. */
-#undef HAVE_VPRINTF
-
-/* Define to 1 if `fork' works. */
-#undef HAVE_WORKING_FORK
-
-/* Define to 1 if `vfork' works. */
-#undef HAVE_WORKING_VFORK
-
-/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
- slash. */
-#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
-
-/* Define to 1 if 'lvm' should fall back to using LVM1 binaries if
- device-mapper is missing from the kernel */
-#undef LVM1_FALLBACK
-
-/* Define to 1 to include built-in support for LVM1 metadata. */
-#undef LVM1_INTERNAL
-
-/* Path to lvmetad pidfile. */
-#undef LVMETAD_PIDFILE
-
-/* Define to 1 to include code that uses lvmetad. */
-#undef LVMETAD_SUPPORT
-
-/* Path to lvm binary. */
-#undef LVM_PATH
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
- */
-#undef MAJOR_IN_MKDEV
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in
- <sysmacros.h>. */
-#undef MAJOR_IN_SYSMACROS
-
-/* Define to 1 to include built-in support for mirrors. */
-#undef MIRRORED_INTERNAL
-
-/* The path to 'modprobe', if available. */
-#undef MODPROBE_CMD
-
-/* Define to 1 to enable O_DIRECT support. */
-#undef O_DIRECT_SUPPORT
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 to include built-in support for GFS pool metadata. */
-#undef POOL_INTERNAL
-
-/* Define to 1 to include built-in support for raid. */
-#undef RAID_INTERNAL
-
-/* Define to 1 to include the LVM readline shell. */
-#undef READLINE_SUPPORT
-
-/* Define to 1 to include built-in support for replicators. */
-#undef REPLICATOR_INTERNAL
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#undef RETSIGTYPE
-
-/* Define to the type of arg 1 for `select'. */
-#undef SELECT_TYPE_ARG1
-
-/* Define to the type of args 2, 3 and 4 for `select'. */
-#undef SELECT_TYPE_ARG234
-
-/* Define to the type of arg 5 for `select'. */
-#undef SELECT_TYPE_ARG5
-
-/* Define to 1 to include built-in support for snapshots. */
-#undef SNAPSHOT_INTERNAL
-
-/* If using the C implementation of alloca, define if you know the
- direction of stack growth for your system; otherwise it will be
- automatically deduced at runtime.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown */
-#undef STACK_DIRECTION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* The path to 'thin_check', if available. */
-#undef THIN_CHECK_CMD
-
-/* Define to 1 to include built-in support for thin provisioning. */
-#undef THIN_INTERNAL
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-#undef TM_IN_SYS_TIME
-
-/* Define to 1 to enable synchronisation with udev processing. */
-#undef UDEV_SYNC_SUPPORT
-
-/* Enable a valgrind aware build of pool */
-#undef VALGRIND_POOL
-
-/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-#undef _UINT32_T
-
-/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-#undef _UINT64_T
-
-/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-#undef _UINT8_T
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef gid_t
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
-#undef inline
-#endif
-
-/* Define to the type of a signed integer type of width exactly 16 bits if
- such a type exists and the standard includes do not define it. */
-#undef int16_t
-
-/* Define to the type of a signed integer type of width exactly 32 bits if
- such a type exists and the standard includes do not define it. */
-#undef int32_t
-
-/* Define to the type of a signed integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-#undef int64_t
-
-/* Define to the type of a signed integer type of width exactly 8 bits if such
- a type exists and the standard includes do not define it. */
-#undef int8_t
-
-/* Define to rpl_malloc if the replacement function should be used. */
-#undef malloc
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef mode_t
-
-/* Define to `long int' if <sys/types.h> does not define. */
-#undef off_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef pid_t
-
-/* Define to rpl_realloc if the replacement function should be used. */
-#undef realloc
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#undef size_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef ssize_t
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef uid_t
-
-/* Define to the type of an unsigned integer type of width exactly 16 bits if
- such a type exists and the standard includes do not define it. */
-#undef uint16_t
-
-/* Define to the type of an unsigned integer type of width exactly 32 bits if
- such a type exists and the standard includes do not define it. */
-#undef uint32_t
-
-/* Define to the type of an unsigned integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-#undef uint64_t
-
-/* Define to the type of an unsigned integer type of width exactly 8 bits if
- such a type exists and the standard includes do not define it. */
-#undef uint8_t
-
-/* Define as `fork' if `vfork' does not work. */
-#undef vfork
diff --git a/lib/misc/crc.c b/lib/misc/crc.c
index c948b77..8dc107f 100644
--- a/lib/misc/crc.c
+++ b/lib/misc/crc.c
@@ -10,13 +10,13 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "lib.h"
+#include "lib/misc/lib.h"
-#include "crc.h"
-#include "xlate.h"
+#include "lib/misc/crc.h"
+#include "lib/mm/xlate.h"
/* Calculate an endian-independent CRC of supplied buffer */
#ifndef DEBUG_CRC32
@@ -63,7 +63,7 @@ static uint32_t _calc_crc_new(uint32_t initial, const uint8_t *buf, uint32_t siz
const uint32_t *start = (const uint32_t *) buf;
const uint32_t *end = (const uint32_t *) (buf + (size & 0xfffffffc));
uint32_t crc = initial;
-
+
/* Process 4 bytes per iteration */
while (start < end) {
crc = crc ^ xlate32(*start++);
diff --git a/lib/misc/crc.h b/lib/misc/crc.h
index 2910bc5..ddaa3e6 100644
--- a/lib/misc/crc.h
+++ b/lib/misc/crc.h
@@ -10,12 +10,14 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_CRC_H
#define _LVM_CRC_H
+#include <inttypes.h>
+
#define INITIAL_CRC 0xf597a6cf
uint32_t calc_crc(uint32_t initial, const uint8_t *buf, uint32_t size);
diff --git a/lib/misc/crc_gen.c b/lib/misc/crc_gen.c
index 5e83317..56f2d25 100644
--- a/lib/misc/crc_gen.c
+++ b/lib/misc/crc_gen.c
@@ -9,13 +9,13 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* Helper program to generate table included in crc.c.
*/
-#include "lib.h"
+#include "lib/misc/lib.h"
int main(int argc, char **argv)
{
diff --git a/lib/misc/intl.h b/lib/misc/intl.h
index fe08021..67fe0a0 100644
--- a/lib/misc/intl.h
+++ b/lib/misc/intl.h
@@ -10,7 +10,7 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_INTL_H
diff --git a/lib/misc/last-path-component.h b/lib/misc/last-path-component.h
index e0d5940..ba4951f 100644
--- a/lib/misc/last-path-component.h
+++ b/lib/misc/last-path-component.h
@@ -9,7 +9,7 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
diff --git a/lib/misc/lib.h b/lib/misc/lib.h
index 100827d..a3a11ba 100644
--- a/lib/misc/lib.h
+++ b/lib/misc/lib.h
@@ -10,7 +10,7 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
@@ -19,30 +19,20 @@
#ifndef _LVM_LIB_H
#define _LVM_LIB_H
-#include "configure.h"
-
-#define _REENTRANT
-#define _GNU_SOURCE
-#define _FILE_OFFSET_BITS 64
-
-#include "intl.h"
-#include "libdevmapper.h"
-#include "lvm-globals.h"
-#include "lvm-wrappers.h"
-#include "lvm-types.h"
-#include "util.h"
+#include "device_mapper/all.h"
+#include "base/memory/zalloc.h"
+#include "lib/misc/intl.h"
+#include "lib/misc/util.h"
#ifdef DM
-# include "dm-logging.h"
+# include "libdm/misc/dm-logging.h"
#else
-# include "lvm-logging.h"
+# include "lib/log/lvm-logging.h"
+# include "lib/misc/lvm-globals.h"
+# include "lib/misc/lvm-wrappers.h"
+# include "lib/misc/lvm-maths.h"
#endif
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
-#include <sys/stat.h>
#endif
diff --git a/lib/misc/lvm-exec.c b/lib/misc/lvm-exec.c
index 4b74a41..172c0fa 100644
--- a/lib/misc/lvm-exec.c
+++ b/lib/misc/lvm-exec.c
@@ -10,15 +10,14 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "lib.h"
-#include "device.h"
-#include "locking.h"
-#include "lvm-exec.h"
-#include "toolcontext.h"
-#include "activate.h"
+#include "lib/misc/lib.h"
+#include "lib/device/device.h"
+#include "lib/locking/locking.h"
+#include "lib/misc/lvm-exec.h"
+#include "lib/commands/toolcontext.h"
#include <unistd.h>
#include <sys/wait.h>
@@ -51,28 +50,34 @@ int exec_cmd(struct cmd_context *cmd, const char *const argv[],
int *rstatus, int sync_needed)
{
pid_t pid;
- int status;
+ int status = 0;
char buf[PATH_MAX * 2];
-
if (rstatus)
*rstatus = -1;
+ if (!argv[0]) {
+ log_error(INTERNAL_ERROR "Missing command.");
+ return 0;
+ }
+
if (sync_needed)
- if (!sync_local_dev_names(cmd)) /* Flush ops and reset dm cookie */
- return_0;
+ /* Flush ops and reset dm cookie */
+ if (!sync_local_dev_names(cmd)) {
+ log_error("Failed to sync local device names before forking.");
+ return 0;
+ }
log_verbose("Executing:%s", _verbose_args(argv, buf, sizeof(buf)));
if ((pid = fork()) == -1) {
- log_error("fork failed: %s", strerror(errno));
+ log_sys_error("fork", "");
return 0;
}
if (!pid) {
/* Child */
reset_locking();
- dev_close_all();
/* FIXME Fix effect of reset_locking on cache then include this */
/* destroy_toolcontext(cmd); */
/* FIXME Use execve directly */
@@ -107,3 +112,139 @@ int exec_cmd(struct cmd_context *cmd, const char *const argv[],
return 1;
}
+
+static int _reopen_fd_to_null(int fd)
+{
+ int null_fd;
+ int r = 0;
+
+ if ((null_fd = open("/dev/null", O_RDWR)) == -1) {
+ log_sys_error("open", "/dev/null");
+ return 0;
+ }
+
+ if (close(fd)) {
+ log_sys_error("close", "");
+ goto out;
+ }
+
+ if (dup2(null_fd, fd) == -1) {
+ log_sys_error("dup2", "");
+ goto out;
+ }
+
+ r = 1;
+out:
+ if (close(null_fd)) {
+ log_sys_error("dup2", "");
+ return 0;
+ }
+
+ return r;
+}
+
+FILE *pipe_open(struct cmd_context *cmd, const char *const argv[],
+ int sync_needed, struct pipe_data *pdata)
+{
+ int pipefd[2];
+ char buf[PATH_MAX * 2];
+
+ if (sync_needed)
+ /* Flush ops and reset dm cookie */
+ if (!sync_local_dev_names(cmd)) {
+ log_error("Failed to sync local device names before forking.");
+ return 0;
+ }
+
+ if (pipe(pipefd)) {
+ log_sys_error("pipe", "");
+ return 0;
+ }
+
+ log_verbose("Piping:%s", _verbose_args(argv, buf, sizeof(buf)));
+
+ if ((pdata->pid = fork()) == -1) {
+ log_sys_error("pipe", "");
+ return 0;
+ }
+
+ if (pdata->pid == 0) {
+ /* Child -> writer, convert pipe[0] to STDOUT */
+ if (!_reopen_fd_to_null(STDIN_FILENO))
+ stack;
+ else if (close(pipefd[0 /*read*/]))
+ log_sys_error("close", "pipe[0]");
+ else if (close(STDOUT_FILENO))
+ log_sys_error("close", "STDOUT");
+ else if (dup2(pipefd[1 /*write*/], STDOUT_FILENO) == -1)
+ log_sys_error("dup2", "STDOUT");
+ else if (close(pipefd[1]))
+ log_sys_error("close", "pipe[1]");
+ else if (argv[0]) {
+ execvp(argv[0], (char **) argv);
+ log_sys_error("execvp", argv[0]);
+ }
+ _exit(errno);
+ }
+
+ /* Parent -> reader */
+ if (close(pipefd[1 /*write*/])) {
+ log_sys_error("close", "STDOUT");
+ return NULL;
+ }
+
+ if (!(pdata->fp = fdopen(pipefd[0 /*read*/], "r"))) {
+ log_sys_error("fdopen", "STDIN");
+ if (close(pipefd[0]))
+ log_sys_error("close", "STDIN");
+ return NULL; /* FIXME: kill */
+ }
+
+ return pdata->fp;
+}
+
+int pipe_close(struct pipe_data *pdata)
+{
+ int status;
+
+ if (fclose(pdata->fp))
+ log_sys_error("fclose", "STDIN");
+
+ if (waitpid(pdata->pid, &status, 0) != pdata->pid) {
+ log_sys_error("waitpid", "");
+ return 0;
+ }
+
+ return (status == 0) ? 1 : 0;
+}
+
+int prepare_exec_args(struct cmd_context *cmd,
+ const char *argv[], int *argc, int options_id)
+{
+ const struct dm_config_value *cv;
+ const struct dm_config_node *cn;
+
+ if (!(cn = find_config_tree_array(cmd, options_id, NULL))) {
+ log_error(INTERNAL_ERROR "Unable to find configuration for %s options.",
+ argv[0]);
+ return 0;
+ }
+
+ for (cv = cn->v; cv; cv = cv->next) {
+ if (*argc >= DEFAULT_MAX_EXEC_ARGS) {
+ log_error("Too many options for %s command.", argv[0]);
+ return 0;
+ }
+
+ if (cv->type != DM_CFG_STRING) {
+ log_error("Invalid string in config file: "
+ "global/%s_options.", argv[0]);
+ return 0;
+ }
+
+ if (cv->v.str[0])
+ argv[++(*argc)] = cv->v.str;
+ }
+
+ return 1;
+}
diff --git a/lib/misc/lvm-exec.h b/lib/misc/lvm-exec.h
index c91ffaf..0429185 100644
--- a/lib/misc/lvm-exec.h
+++ b/lib/misc/lvm-exec.h
@@ -10,13 +10,13 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_EXEC_H
#define _LVM_EXEC_H
-#include "lib.h"
+#include "lib/misc/lib.h"
struct cmd_context;
@@ -32,9 +32,43 @@ struct cmd_context;
* Note: You cannot synchronize devices within activation context.
*
* \return
- * 0 (success) or -1 (failure).
+ * 1 (success) or 0 (failure).
*/
int exec_cmd(struct cmd_context *cmd, const char *const argv[],
int *rstatus, int sync_needed);
+
+struct FILE;
+struct pipe_data {
+ FILE *fp;
+ pid_t pid;
+};
+
+/**
+ * popen() like function to read-only output from executed command
+ * without running shell.
+ *
+ * \param argv
+ * Arguments for execvp.
+ *
+ * \param sync_needed
+ * Bool specifying whether local devices needs to be synchronized
+ * before executing command.
+ * Note: You cannot synchronize devices within activation context.
+ *
+ * \param pdata
+ * Arguments to store data needed for pclose_exec().
+ *
+ * \return
+ * 1 (success) or 0 (failure).
+ */
+FILE *pipe_open(struct cmd_context *cmd, const char *const argv[],
+ int sync_needed, struct pipe_data *pdata);
+
+int pipe_close(struct pipe_data *pdata);
+
+/* Prepare argv options list */
+int prepare_exec_args(struct cmd_context *cmd,
+ const char *argv[], int *argc, int options_id);
+
#endif
diff --git a/lib/misc/lvm-file.c b/lib/misc/lvm-file.c
index b8e49cb..4a3479a 100644
--- a/lib/misc/lvm-file.c
+++ b/lib/misc/lvm-file.c
@@ -10,11 +10,11 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "lib.h"
-#include "lvm-file.h"
+#include "lib/misc/lib.h"
+#include "lib/misc/lvm-file.h"
#include <unistd.h>
#include <sys/stat.h>
@@ -31,24 +31,18 @@
int create_temp_name(const char *dir, char *buffer, size_t len, int *fd,
unsigned *seed)
{
+ const struct flock lock = { .l_type = F_WRLCK };
int i, num;
pid_t pid;
char hostname[255];
char *p;
- struct flock lock = {
- .l_type = F_WRLCK,
- .l_whence = 0,
- .l_start = 0,
- .l_len = 0
- };
num = rand_r(seed);
pid = getpid();
if (gethostname(hostname, sizeof(hostname)) < 0) {
log_sys_error("gethostname", "");
strcpy(hostname, "nohostname");
- }
- else {
+ } else {
/* Replace any '/' with '?' found in the hostname. */
p = hostname;
while ((p = strchr(p, '/')))
@@ -147,33 +141,12 @@ int dir_exists(const char *path)
return 1;
}
-int is_empty_dir(const char *dir)
-{
- struct dirent *dirent;
- DIR *d;
-
- if (!(d = opendir(dir))) {
- log_sys_error("opendir", dir);
- return 0;
- }
-
- while ((dirent = readdir(d)))
- if (strcmp(dirent->d_name, ".") && strcmp(dirent->d_name, ".."))
- break;
-
- if (closedir(d)) {
- log_sys_error("closedir", dir);
- }
-
- return dirent ? 0 : 1;
-}
-
void sync_dir(const char *file)
{
int fd;
char *dir, *c;
- if (!(dir = dm_strdup(file))) {
+ if (!(dir = strdup(file))) {
log_error("sync_dir failed in strdup");
return;
}
@@ -201,7 +174,7 @@ void sync_dir(const char *file)
log_sys_error("close", dir);
out:
- dm_free(dir);
+ free(dir);
}
/*
@@ -212,17 +185,12 @@ void sync_dir(const char *file)
*/
int fcntl_lock_file(const char *file, short lock_type, int warn_if_read_only)
{
+ const struct flock lock = { .l_type = lock_type };
int lockfd;
char *dir;
char *c;
- struct flock lock = {
- .l_type = lock_type,
- .l_whence = 0,
- .l_start = 0,
- .l_len = 0
- };
-
- if (!(dir = dm_strdup(file))) {
+
+ if (!(dir = strdup(file))) {
log_error("fcntl_lock_file failed in strdup.");
return -1;
}
@@ -231,11 +199,11 @@ int fcntl_lock_file(const char *file, short lock_type, int warn_if_read_only)
*c = '\0';
if (!dm_create_dir(dir)) {
- dm_free(dir);
+ free(dir);
return -1;
}
- dm_free(dir);
+ free(dir);
log_very_verbose("Locking %s (%s, %hd)", file,
(lock_type == F_WRLCK) ? "F_WRLCK" : "F_RDLCK",
@@ -253,7 +221,7 @@ int fcntl_lock_file(const char *file, short lock_type, int warn_if_read_only)
if (fcntl(lockfd, F_SETLKW, &lock)) {
log_sys_error("fcntl", file);
if (close(lockfd))
- log_sys_error("close", file);
+ log_sys_error("close", file);
return -1;
}
@@ -262,31 +230,36 @@ int fcntl_lock_file(const char *file, short lock_type, int warn_if_read_only)
void fcntl_unlock_file(int lockfd)
{
- struct flock lock = {
- .l_type = F_UNLCK,
- .l_whence = 0,
- .l_start = 0,
- .l_len = 0
- };
+ const struct flock lock = { .l_type = F_UNLCK };
log_very_verbose("Unlocking fd %d", lockfd);
if (fcntl(lockfd, F_SETLK, &lock) == -1)
- log_error("fcntl unlock failed on fd %d: %s", lockfd,
- strerror(errno));
+ log_sys_error("fcntl", "");
if (close(lockfd))
- log_error("lock file close failed on fd %d: %s", lockfd,
- strerror(errno));
+ log_sys_error("close","");
}
int lvm_fclose(FILE *fp, const char *filename)
{
if (!dm_fclose(fp))
return 0;
+
if (errno == 0)
log_error("%s: write error", filename);
else
log_sys_error("write error", filename);
+
return EOF;
}
+
+void lvm_stat_ctim(struct timespec *ctim, const struct stat *buf)
+{
+#ifdef HAVE_STAT_ST_CTIM
+ *ctim = buf->st_ctim;
+#else
+ ctim->tv_sec = buf->st_ctime;
+ ctim->tv_nsec = 0;
+#endif
+}
diff --git a/lib/misc/lvm-file.h b/lib/misc/lvm-file.h
index c23d8ad..4c405e6 100644
--- a/lib/misc/lvm-file.h
+++ b/lib/misc/lvm-file.h
@@ -10,12 +10,18 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_FILE_H
#define _LVM_FILE_H
+struct custom_fds {
+ int out;
+ int err;
+ int report;
+};
+
/*
* Create a temporary filename, and opens a descriptor to the file.
*/
@@ -35,11 +41,6 @@ int lvm_rename(const char *old, const char *new);
int path_exists(const char *path);
int dir_exists(const char *path);
-/*
- * Return 1 if dir is empty
- */
-int is_empty_dir(const char *dir);
-
/* Sync directory changes */
void sync_dir(const char *file);
@@ -62,4 +63,15 @@ void fcntl_unlock_file(int lockfd);
*/
int lvm_fclose(FILE *fp, const char *filename);
+/*
+ * Convert stat->st_ctim status of last change in nanoseconds
+ * uses st_ctime when not available.
+ */
+void lvm_stat_ctim(struct timespec *ts, const struct stat *buf);
+
+/* Inspired by <sys/time.h> timercmp() macro for timeval */
+#define timespeccmp(tsp, usp, cmp)\
+ (((tsp)->tv_sec == (usp)->tv_sec) ?\
+ ((tsp)->tv_nsec cmp (usp)->tv_nsec) :\
+ ((tsp)->tv_sec cmp (usp)->tv_sec))
#endif
diff --git a/lib/misc/lvm-flock.c b/lib/misc/lvm-flock.c
new file mode 100644
index 0000000..d48ff22
--- /dev/null
+++ b/lib/misc/lvm-flock.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "lib/misc/lib.h"
+#include "lib/config/config.h"
+#include "lib/misc/lvm-flock.h"
+#include "lib/misc/lvm-signal.h"
+#include "lib/locking/locking.h"
+
+#include <sys/file.h>
+#include <fcntl.h>
+
+struct lock_list {
+ struct dm_list list;
+ int lf;
+ char *res;
+};
+
+static struct dm_list _lock_list;
+static int _prioritise_write_locks;
+
+/* Drop lock known to be shared with another file descriptor. */
+static void _drop_shared_flock(const char *file, int fd)
+{
+ log_debug_locking("_drop_shared_flock %s.", file);
+
+ if (close(fd) < 0)
+ log_sys_debug("close", file);
+}
+
+static void _undo_flock(const char *file, int fd)
+{
+ struct stat buf1, buf2;
+
+ log_debug_locking("_undo_flock %s", file);
+ if (!flock(fd, LOCK_NB | LOCK_EX) &&
+ !stat(file, &buf1) &&
+ !fstat(fd, &buf2) &&
+ is_same_inode(buf1, buf2))
+ if (unlink(file))
+ log_sys_debug("unlink", file);
+
+ if (close(fd) < 0)
+ log_sys_debug("close", file);
+}
+
+static struct lock_list *_get_lock_list_entry(const char *file)
+{
+ struct lock_list *ll;
+ struct dm_list *llh;
+
+ dm_list_iterate(llh, &_lock_list) {
+ ll = dm_list_item(llh, struct lock_list);
+
+ if (!strcmp(ll->res, file))
+ return ll;
+ }
+ return NULL;
+}
+
+static int _release_lock(const char *file, int unlock)
+{
+ struct lock_list *ll;
+ struct dm_list *llh, *llt;
+
+ dm_list_iterate_safe(llh, llt, &_lock_list) {
+ ll = dm_list_item(llh, struct lock_list);
+
+ if (!file || !strcmp(ll->res, file)) {
+ dm_list_del(llh);
+ if (unlock) {
+ log_very_verbose("Unlocking %s", ll->res);
+ if (flock(ll->lf, LOCK_NB | LOCK_UN))
+ log_sys_debug("flock", ll->res);
+ _undo_flock(ll->res, ll->lf);
+ } else
+ _drop_shared_flock(ll->res, ll->lf);
+
+ free(ll->res);
+ free(llh);
+
+ if (file)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void release_flocks(int unlock)
+{
+ _release_lock(NULL, unlock);
+}
+
+static int _do_flock(const char *file, int *fd, int operation, uint32_t nonblock)
+{
+ int r;
+ int old_errno;
+ struct stat buf1, buf2;
+
+ log_debug_locking("_do_flock %s %c%c", file,
+ operation == LOCK_EX ? 'W' : 'R', nonblock ? ' ' : 'B');
+ do {
+ if ((*fd > -1) && close(*fd))
+ log_sys_debug("close", file);
+
+ if ((*fd = open(file, O_CREAT | O_APPEND | O_RDWR, 0777)) < 0) {
+ log_sys_error("open", file);
+ return 0;
+ }
+
+ if (nonblock)
+ operation |= LOCK_NB;
+ else
+ sigint_allow();
+
+ r = flock(*fd, operation);
+ old_errno = errno;
+ if (!nonblock) {
+ sigint_restore();
+ if (sigint_caught()) {
+ log_error("Giving up waiting for lock.");
+ break;
+ }
+ }
+
+ if (r) {
+ errno = old_errno;
+ log_sys_error("flock", file);
+ break;
+ }
+
+ if (!stat(file, &buf1) && !fstat(*fd, &buf2) &&
+ is_same_inode(buf1, buf2))
+ return 1;
+ } while (!nonblock);
+
+ if (close(*fd))
+ log_sys_debug("close", file);
+ *fd = -1;
+
+ return_0;
+}
+
+#define AUX_LOCK_SUFFIX ":aux"
+
+static int _do_write_priority_flock(const char *file, int *fd, int operation, uint32_t nonblock)
+{
+ int r, fd_aux = -1;
+ char *file_aux = alloca(strlen(file) + sizeof(AUX_LOCK_SUFFIX));
+
+ strcpy(file_aux, file);
+ strcat(file_aux, AUX_LOCK_SUFFIX);
+
+ if ((r = _do_flock(file_aux, &fd_aux, LOCK_EX, nonblock))) {
+ if (operation == LOCK_EX) {
+ r = _do_flock(file, fd, operation, nonblock);
+ _undo_flock(file_aux, fd_aux);
+ } else {
+ _undo_flock(file_aux, fd_aux);
+ r = _do_flock(file, fd, operation, nonblock);
+ }
+ }
+
+ return r;
+}
+
+int lock_file(const char *file, uint32_t flags)
+{
+ int operation;
+ uint32_t nonblock = flags & LCK_NONBLOCK;
+ uint32_t convert = flags & LCK_CONVERT;
+ int r;
+ struct lock_list *ll;
+ char state;
+
+ switch (flags & LCK_TYPE_MASK) {
+ case LCK_READ:
+ operation = LOCK_SH;
+ state = 'R';
+ break;
+ case LCK_WRITE:
+ operation = LOCK_EX;
+ state = 'W';
+ break;
+ case LCK_UNLOCK:
+ return _release_lock(file, 1);
+ default:
+ log_error("Unrecognised lock type: %d", flags & LCK_TYPE_MASK);
+ return 0;
+ }
+
+ if (convert) {
+ if (nonblock)
+ operation |= LOCK_NB;
+ if (!(ll = _get_lock_list_entry(file)))
+ return 0;
+ log_very_verbose("Locking %s %c%c convert", ll->res, state,
+ nonblock ? ' ' : 'B');
+ r = flock(ll->lf, operation);
+ if (!r)
+ return 1;
+ log_error("Failed to convert flock on %s %d", file, errno);
+ return 0;
+ }
+
+ if (!(ll = malloc(sizeof(struct lock_list))))
+ return_0;
+
+ if (!(ll->res = strdup(file))) {
+ free(ll);
+ return_0;
+ }
+
+ ll->lf = -1;
+
+ log_very_verbose("Locking %s %c%c", ll->res, state,
+ nonblock ? ' ' : 'B');
+
+ (void) dm_prepare_selinux_context(file, S_IFREG);
+ if (_prioritise_write_locks)
+ r = _do_write_priority_flock(file, &ll->lf, operation, nonblock);
+ else
+ r = _do_flock(file, &ll->lf, operation, nonblock);
+ (void) dm_prepare_selinux_context(NULL, 0);
+
+ if (r)
+ dm_list_add(&_lock_list, &ll->list);
+ else {
+ free(ll->res);
+ free(ll);
+ stack;
+ }
+
+ return r;
+}
+
+void init_flock(struct cmd_context *cmd)
+{
+ dm_list_init(&_lock_list);
+
+ _prioritise_write_locks =
+ find_config_tree_bool(cmd, global_prioritise_write_locks_CFG, NULL);
+}
diff --git a/lib/misc/lvm-flock.h b/lib/misc/lvm-flock.h
new file mode 100644
index 0000000..a6c7e36
--- /dev/null
+++ b/lib/misc/lvm-flock.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _LVM_FLOCK_H
+#define _LVM_FLOCK_H
+
+void init_flock(struct cmd_context *cmd);
+int lock_file(const char *file, uint32_t flags);
+void release_flocks(int unlock);
+
+#endif /* _LVM_FLOCK_H */
diff --git a/lib/misc/lvm-globals.c b/lib/misc/lvm-globals.c
index fe38008..06855ff 100644
--- a/lib/misc/lvm-globals.c
+++ b/lib/misc/lvm-globals.c
@@ -10,45 +10,50 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "lib.h"
-#include "device.h"
-#include "memlock.h"
-#include "lvm-string.h"
-#include "defaults.h"
-#include "metadata-exported.h"
+#include "lib/misc/lib.h"
+#include "lib/device/device.h"
+#include "lib/misc/lvm-string.h"
+#include "lib/config/defaults.h"
+#include "lib/metadata/metadata-exported.h"
#include <stdarg.h>
static int _verbose_level = VERBOSE_BASE_LEVEL;
static int _silent = 0;
static int _test = 0;
+static int _use_aio = 0;
static int _md_filtering = 0;
+static int _internal_filtering = 0;
+static int _fwraid_filtering = 0;
static int _pvmove = 0;
-static int _full_scan_done = 0; /* Restrict to one full scan during each cmd */
static int _obtain_device_list_from_udev = DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV;
-static int _trust_cache = 0; /* Don't scan when incomplete VGs encountered */
+static enum dev_ext_e _external_device_info_source = DEV_EXT_NONE;
static int _debug_level = 0;
-static int _log_cmd_name = 0;
-static int _ignorelockingfailure = 0;
+static int _debug_classes_logged = 0;
static int _security_level = SECURITY_LEVEL;
-static char _cmd_name[30] = "";
+static char _log_command_info[40] = "";
+static char _log_command_file[40] = "";
+static char _cmd_name[30] = "none";
static int _mirror_in_sync = 0;
static int _dmeventd_monitor = DEFAULT_DMEVENTD_MONITOR;
+/* When set, disables update of _dmeventd_monitor & _ignore_suspended_devices */
+static int _disable_dmeventd_monitoring = 0;
static int _background_polling = DEFAULT_BACKGROUND_POLLING;
static int _ignore_suspended_devices = 0;
+static int _ignore_lvm_mirrors = DEFAULT_IGNORE_LVM_MIRRORS;
static int _error_message_produced = 0;
static unsigned _is_static = 0;
static int _udev_checking = 1;
+static int _udev_sleeping = 1;
static int _retry_deactivation = DEFAULT_RETRY_DEACTIVATION;
static int _activation_checks = 0;
static char _sysfs_dir_path[PATH_MAX] = "";
-static int _dev_disable_after_error_count = DEFAULT_DISABLE_AFTER_ERROR_COUNT;
static uint64_t _pv_min_size = (DEFAULT_PV_MIN_SIZE_KB * 1024L >> SECTOR_SHIFT);
-static int _detect_internal_vg_cache_corruption =
- DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION;
+static const char *_unknown_device_name = DEFAULT_UNKNOWN_DEVICE_NAME;
+static int _io_memory_size_kb = DEFAULT_IO_MEMORY_SIZE_KB;
void init_verbose(int level)
{
@@ -67,34 +72,39 @@ void init_test(int level)
_test = level;
}
+void init_use_aio(int useaio)
+{
+ _use_aio = useaio;
+}
+
void init_md_filtering(int level)
{
_md_filtering = level;
}
-void init_pvmove(int level)
+void init_internal_filtering(int level)
{
- _pvmove = level;
+ _internal_filtering = level;
}
-void init_full_scan_done(int level)
+void init_fwraid_filtering(int level)
{
- _full_scan_done = level;
+ _fwraid_filtering = level;
}
-void init_obtain_device_list_from_udev(int device_list_from_udev)
+void init_pvmove(int level)
{
- _obtain_device_list_from_udev = device_list_from_udev;
+ _pvmove = level;
}
-void init_trust_cache(int trustcache)
+void init_obtain_device_list_from_udev(int device_list_from_udev)
{
- _trust_cache = trustcache;
+ _obtain_device_list_from_udev = device_list_from_udev;
}
-void init_ignorelockingfailure(int level)
+void init_external_device_info_source(enum dev_ext_e src)
{
- _ignorelockingfailure = level;
+ _external_device_info_source = src;
}
void init_security_level(int level)
@@ -109,7 +119,13 @@ void init_mirror_in_sync(int in_sync)
void init_dmeventd_monitor(int reg)
{
- _dmeventd_monitor = reg;
+ if (!_disable_dmeventd_monitoring)
+ _dmeventd_monitor = reg;
+}
+
+void init_disable_dmeventd_monitoring(int reg)
+{
+ _disable_dmeventd_monitoring = reg;
}
void init_background_polling(int polling)
@@ -119,12 +135,43 @@ void init_background_polling(int polling)
void init_ignore_suspended_devices(int ignore)
{
- _ignore_suspended_devices = ignore;
+ if (!_disable_dmeventd_monitoring)
+ _ignore_suspended_devices = ignore;
}
-void init_cmd_name(int status)
+void init_ignore_lvm_mirrors(int scan)
{
- _log_cmd_name = status;
+ _ignore_lvm_mirrors = scan;
+}
+
+void init_log_command(int log_name, int log_pid)
+{
+ memset(_log_command_info, 0, sizeof(_log_command_info));
+ memset(_log_command_file, 0, sizeof(_log_command_file));
+
+ /*
+ * Always include command name and pid in file and verbose output.
+ */
+
+ (void) dm_snprintf(_log_command_file, sizeof(_log_command_file), "%s[%d]",
+ _cmd_name, getpid());
+
+ /*
+ * This is the prefix that can be configured for each line of stdout.
+ */
+
+ if (!log_name && !log_pid)
+ return;
+
+ else if (log_name && !log_pid)
+ (void) dm_strncpy(_log_command_info, _cmd_name, sizeof(_log_command_info));
+
+ else if (!log_name && log_pid)
+ (void) dm_snprintf(_log_command_info, sizeof(_log_command_info), "%d", getpid());
+
+ else
+ (void) dm_snprintf(_log_command_info, sizeof(_log_command_info), "%s[%d]",
+ _cmd_name, getpid());
}
void init_is_static(unsigned value)
@@ -135,9 +182,14 @@ void init_is_static(unsigned value)
void init_udev_checking(int checking)
{
if ((_udev_checking = checking))
- log_debug("LVM udev checking enabled");
+ log_debug_activation("LVM udev checking enabled");
else
- log_debug("LVM udev checking disabled");
+ log_debug_activation("LVM udev checking disabled");
+}
+
+void init_udev_sleeping(int sleeping)
+{
+ _udev_sleeping = sleeping;
}
void init_retry_deactivation(int retry)
@@ -148,14 +200,9 @@ void init_retry_deactivation(int retry)
void init_activation_checks(int checks)
{
if ((_activation_checks = checks))
- log_debug("LVM activation checks enabled");
+ log_debug_activation("LVM activation checks enabled");
else
- log_debug("LVM activation checks disabled");
-}
-
-void init_dev_disable_after_error_count(int value)
-{
- _dev_disable_after_error_count = value;
+ log_debug_activation("LVM activation checks disabled");
}
void init_pv_min_size(uint64_t sectors)
@@ -163,29 +210,29 @@ void init_pv_min_size(uint64_t sectors)
_pv_min_size = sectors;
}
-void init_detect_internal_vg_cache_corruption(int detect)
+void set_cmd_name(const char *cmd)
{
- _detect_internal_vg_cache_corruption = detect;
+ (void) dm_strncpy(_cmd_name, cmd, sizeof(_cmd_name));
}
-void set_cmd_name(const char *cmd)
+const char *get_cmd_name(void)
{
- strncpy(_cmd_name, cmd, sizeof(_cmd_name) - 1);
- _cmd_name[sizeof(_cmd_name) - 1] = '\0';
+ return _cmd_name;
}
void set_sysfs_dir_path(const char *path)
{
- strncpy(_sysfs_dir_path, path, sizeof(_sysfs_dir_path) - 1);
- _sysfs_dir_path[sizeof(_sysfs_dir_path) - 1] = '\0';
+ (void) dm_strncpy(_sysfs_dir_path, path, sizeof(_sysfs_dir_path));
}
-const char *log_command_name(void)
+const char *log_command_info(void)
{
- if (!_log_cmd_name)
- return "";
+ return _log_command_info;
+}
- return _cmd_name;
+const char *log_command_file(void)
+{
+ return _log_command_file;
}
void init_error_message_produced(int value)
@@ -203,19 +250,29 @@ int test_mode(void)
return _test;
}
+int use_aio(void)
+{
+ return _use_aio;
+}
+
int md_filtering(void)
{
return _md_filtering;
}
-int pvmove_mode(void)
+int internal_filtering(void)
{
- return _pvmove;
+ return _internal_filtering;
}
-int full_scan_done(void)
+int fwraid_filtering(void)
+{
+ return _fwraid_filtering;
+}
+
+int pvmove_mode(void)
{
- return _full_scan_done;
+ return _pvmove;
}
int obtain_device_list_from_udev(void)
@@ -223,9 +280,9 @@ int obtain_device_list_from_udev(void)
return _obtain_device_list_from_udev;
}
-int trust_cache(void)
+enum dev_ext_e external_device_info_source(void)
{
- return _trust_cache;
+ return _external_device_info_source;
}
int background_polling(void)
@@ -233,11 +290,6 @@ int background_polling(void)
return _background_polling;
}
-int ignorelockingfailure(void)
-{
- return _ignorelockingfailure;
-}
-
int security_level(void)
{
return _security_level;
@@ -258,11 +310,30 @@ int ignore_suspended_devices(void)
return _ignore_suspended_devices;
}
+int ignore_lvm_mirrors(void)
+{
+ return _ignore_lvm_mirrors;
+}
+
void init_debug(int level)
{
_debug_level = level;
}
+void init_debug_classes_logged(int classes)
+{
+ _debug_classes_logged = classes;
+}
+
+int debug_class_is_logged(int class)
+{
+ /* If no class given, log it */
+ if (!class)
+ return 1;
+
+ return (_debug_classes_logged & class) ? 1 : 0;
+}
+
int verbose_level(void)
{
return _verbose_level;
@@ -288,6 +359,11 @@ int udev_checking(void)
return _udev_checking;
}
+int udev_sleeping(void)
+{
+ return _udev_sleeping;
+}
+
int retry_deactivation(void)
{
return _retry_deactivation;
@@ -303,17 +379,27 @@ const char *sysfs_dir_path(void)
return _sysfs_dir_path;
}
-int dev_disable_after_error_count(void)
+uint64_t pv_min_size(void)
+{
+ return _pv_min_size;
+}
+
+const char *unknown_device_name(void)
{
- return _dev_disable_after_error_count;
+ return _unknown_device_name;
}
-uint64_t pv_min_size(void)
+void init_unknown_device_name(const char *name)
{
- return _pv_min_size;
+ _unknown_device_name = name;
+}
+
+int io_memory_size(void)
+{
+ return _io_memory_size_kb;
}
-int detect_internal_vg_cache_corruption(void)
+void init_io_memory_size(int val)
{
- return _detect_internal_vg_cache_corruption;
+ _io_memory_size_kb = val;
}
diff --git a/lib/misc/lvm-globals.h b/lib/misc/lvm-globals.h
index 7fe3288..a54001c 100644
--- a/lib/misc/lvm-globals.h
+++ b/lib/misc/lvm-globals.h
@@ -10,7 +10,7 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_GLOBALS_H
@@ -20,63 +20,73 @@
#define SECURITY_LEVEL 0
#define PV_MIN_SIZE_KB 512
+enum dev_ext_e;
+
void init_verbose(int level);
void init_silent(int silent);
void init_test(int level);
+void init_use_aio(int useaio);
void init_md_filtering(int level);
+void init_internal_filtering(int level);
+void init_fwraid_filtering(int level);
void init_pvmove(int level);
-void init_full_scan_done(int level);
+void init_external_device_info_source(enum dev_ext_e src);
void init_obtain_device_list_from_udev(int device_list_from_udev);
-void init_trust_cache(int trustcache);
void init_debug(int level);
+void init_debug_classes_logged(int classes);
void init_cmd_name(int status);
-void init_ignorelockingfailure(int level);
-void init_lockingfailed(int level);
+void init_log_command(int log_name, int log_pid);
void init_security_level(int level);
void init_mirror_in_sync(int in_sync);
void init_dmeventd_monitor(int reg);
+void init_disable_dmeventd_monitoring(int disable);
void init_background_polling(int polling);
void init_ignore_suspended_devices(int ignore);
+void init_ignore_lvm_mirrors(int scan);
void init_error_message_produced(int produced);
void init_is_static(unsigned value);
void init_udev_checking(int checking);
-void init_dev_disable_after_error_count(int value);
+void init_udev_sleeping(int sleeping);
void init_pv_min_size(uint64_t sectors);
void init_activation_checks(int checks);
-void init_detect_internal_vg_cache_corruption(int detect);
void init_retry_deactivation(int retry);
+void init_unknown_device_name(const char *name);
+void init_io_memory_size(int val);
void set_cmd_name(const char *cmd_name);
+const char *get_cmd_name(void);
void set_sysfs_dir_path(const char *path);
int test_mode(void);
+int use_aio(void);
int md_filtering(void);
+int internal_filtering(void);
+int fwraid_filtering(void);
int pvmove_mode(void);
-int full_scan_done(void);
int obtain_device_list_from_udev(void);
-int trust_cache(void);
+enum dev_ext_e external_device_info_source(void);
int verbose_level(void);
int silent_mode(void);
int debug_level(void);
-int ignorelockingfailure(void);
-int lockingfailed(void);
+int debug_class_is_logged(int class);
int security_level(void);
int mirror_in_sync(void);
int background_polling(void);
int ignore_suspended_devices(void);
-const char *log_command_name(void);
+int ignore_lvm_mirrors(void);
+const char *log_command_info(void);
+const char *log_command_file(void);
unsigned is_static(void);
int udev_checking(void);
+int udev_sleeping(void);
const char *sysfs_dir_path(void);
uint64_t pv_min_size(void);
int activation_checks(void);
-int detect_internal_vg_cache_corruption(void);
int retry_deactivation(void);
+const char *unknown_device_name(void);
+int io_memory_size(void);
#define DMEVENTD_MONITOR_IGNORE -1
int dmeventd_monitor_mode(void);
-#define NO_DEV_ERROR_COUNT_LIMIT 0
-int dev_disable_after_error_count(void);
-
#endif
diff --git a/lib/misc/lvm-maths.c b/lib/misc/lvm-maths.c
new file mode 100644
index 0000000..ede073b
--- /dev/null
+++ b/lib/misc/lvm-maths.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "lib/misc/lib.h"
+
+/* Greatest common divisor */
+unsigned long gcd(unsigned long n1, unsigned long n2)
+{
+ unsigned long remainder;
+
+ do {
+ remainder = n1 % n2;
+ n1 = n2;
+ n2 = remainder;
+ } while (n2);
+
+ return n1;
+}
+
+/* Least common multiple */
+unsigned long lcm(unsigned long n1, unsigned long n2)
+{
+ if (!n1 || !n2)
+ return 0;
+
+ return (n1 * n2) / gcd(n1, n2);
+}
diff --git a/lib/misc/lvm-maths.h b/lib/misc/lvm-maths.h
new file mode 100644
index 0000000..f7fc0ad
--- /dev/null
+++ b/lib/misc/lvm-maths.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _LVM_MATH_H
+#define _LVM_MATH_H
+
+/* Greatest common divisor */
+unsigned long gcd(unsigned long n1, unsigned long n2);
+
+/* Least common multiple */
+unsigned long lcm(unsigned long n1, unsigned long n2);
+
+#endif
diff --git a/lib/misc/lvm-percent.c b/lib/misc/lvm-percent.c
index 4b73db4..f76ae81 100644
--- a/lib/misc/lvm-percent.c
+++ b/lib/misc/lvm-percent.c
@@ -9,32 +9,14 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "lvm-percent.h"
+#include "lib/misc/lib.h"
+#include "lib/misc/lvm-percent.h"
-float percent_to_float(percent_t v)
+uint32_t percent_of_extents(uint32_t percents, uint32_t count, int roundup)
{
- return (float)v / PERCENT_1;
+ return (uint32_t)(((uint64_t)percents * (uint64_t)count +
+ ((roundup) ? 99 : 0)) / 100);
}
-
-percent_t make_percent(uint64_t numerator, uint64_t denominator)
-{
- percent_t percent;
- if (!denominator)
- return PERCENT_100; /* FIXME? */
- if (!numerator)
- return PERCENT_0;
- if (numerator == denominator)
- return PERCENT_100;
- switch (percent = PERCENT_100 * ((double) numerator / (double) denominator)) {
- case PERCENT_100:
- return PERCENT_100 - 1;
- case PERCENT_0:
- return PERCENT_0 + 1;
- default:
- return percent;
- }
-}
-
diff --git a/lib/misc/lvm-percent.h b/lib/misc/lvm-percent.h
index bf30a7e..2ff7199 100644
--- a/lib/misc/lvm-percent.h
+++ b/lib/misc/lvm-percent.h
@@ -9,36 +9,30 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_PERCENT_H
#define _LVM_PERCENT_H
#include <stdint.h>
-/*
- * A fixed-point representation of percent values. One percent equals to
- * PERCENT_1 as defined below. Values that are not multiples of PERCENT_1
- * represent fractions, with precision of 1/1000000 of a percent. See
- * percent_to_float for a conversion to a floating-point representation.
- *
- * You should always use make_percent when building percent_t values. The
- * implementation of make_percent is biased towards the middle: it ensures that
- * the result is PERCENT_0 or PERCENT_100 if and only if this is the actual
- * value -- it never rounds any intermediate value (> 0 or < 100) to either 0
- * or 100.
- */
-typedef int32_t percent_t;
+typedef enum {
+ SIGN_NONE = 0,
+ SIGN_PLUS = 1,
+ SIGN_MINUS = 2
+} sign_t;
typedef enum {
- PERCENT_0 = 0,
- PERCENT_1 = 1000000,
- PERCENT_100 = 100 * PERCENT_1,
- PERCENT_INVALID = -1,
- PERCENT_MERGE_FAILED = -2
-} percent_range_t;
+ PERCENT_NONE = 0,
+ PERCENT_VG,
+ PERCENT_FREE,
+ PERCENT_LV,
+ PERCENT_PVS,
+ PERCENT_ORIGIN
+} percent_type_t;
+
+#define LVM_PERCENT_MERGE_FAILED DM_PERCENT_FAILED
-float percent_to_float(percent_t v);
-percent_t make_percent(uint64_t numerator, uint64_t denominator);
+uint32_t percent_of_extents(uint32_t percents, uint32_t count, int roundup);
#endif
diff --git a/lib/misc/lvm-signal.c b/lib/misc/lvm-signal.c
new file mode 100644
index 0000000..d72417b
--- /dev/null
+++ b/lib/misc/lvm-signal.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "lib/misc/lib.h"
+#include "lib/misc/lvm-signal.h"
+#include "lib/mm/memlock.h"
+
+#include <signal.h>
+
+static sigset_t _oldset;
+static int _signals_blocked = 0;
+static volatile sig_atomic_t _sigint_caught = 0;
+static volatile sig_atomic_t _handler_installed = 0;
+
+/* Support 3 level nesting, increase if needed more */
+#define MAX_SIGINTS 3
+
+struct ar_sigs {
+ int sig;
+ const char *name;
+ int oldmasked[MAX_SIGINTS];
+ struct sigaction oldhandler[MAX_SIGINTS];
+};
+
+/* List of signals we want to allow/restore */
+static struct ar_sigs _ar_sigs[] = {
+ { SIGINT, "SIGINT" },
+ { SIGTERM, "SIGTERM" },
+};
+
+static void _catch_sigint(int unused __attribute__((unused)))
+{
+ _sigint_caught = 1;
+}
+
+int sigint_caught(void) {
+ if (_sigint_caught)
+ log_error("Interrupted...");
+
+ return _sigint_caught;
+}
+
+void sigint_clear(void)
+{
+ _sigint_caught = 0;
+}
+
+/*
+ * Temporarily allow keyboard interrupts to be intercepted and noted;
+ * saves interrupt handler state for sigint_restore(). Users should
+ * use the sigint_caught() predicate to check whether interrupt was
+ * requested and act appropriately. Interrupt flags are never
+ * cleared automatically by this code, but the tools clear the flag
+ * before running each command in lvm_run_command(). All other places
+ * where the flag needs to be cleared need to call sigint_clear().
+ */
+
+void sigint_allow(void)
+{
+ unsigned i, mask = 0;
+ struct sigaction handler;
+ sigset_t sigs;
+
+ if (memlock_count_daemon())
+ return;
+ /*
+ * Do not overwrite the backed-up handler data -
+ * just increase nesting count.
+ */
+ if (++_handler_installed > MAX_SIGINTS)
+ return;
+
+ /* Unmask signals. Remember to mask it again on restore. */
+ if (sigprocmask(0, NULL, &sigs))
+ log_sys_debug("sigprocmask", "");
+
+ for (i = 0; i < DM_ARRAY_SIZE(_ar_sigs); ++i) {
+ /* Grab old sigaction for SIGNAL: shall not fail. */
+ if (sigaction(_ar_sigs[i].sig, NULL, &handler))
+ log_sys_debug("sigaction", _ar_sigs[i].name);
+
+ handler.sa_flags &= ~SA_RESTART; /* Clear restart flag */
+ handler.sa_handler = _catch_sigint;
+
+ /* Override the signal handler: shall not fail. */
+ if (sigaction(_ar_sigs[i].sig, &handler, &_ar_sigs[i].oldhandler[_handler_installed - 1]))
+ log_sys_debug("sigaction", _ar_sigs[i].name);
+
+ if ((_ar_sigs[i].oldmasked[_handler_installed - 1] = sigismember(&sigs, _ar_sigs[i].sig))) {
+ sigdelset(&sigs, _ar_sigs[i].sig);
+ mask = 1;
+ }
+ }
+
+ if (mask && sigprocmask(SIG_SETMASK, &sigs, NULL))
+ log_sys_debug("sigprocmask", "SIG_SETMASK");
+}
+
+void sigint_restore(void)
+{
+ unsigned i, mask = 0;
+ sigset_t sigs;
+
+ if (memlock_count_daemon())
+ return;
+
+ if (!_handler_installed ||
+ --_handler_installed >= MAX_SIGINTS)
+ return;
+
+ /* Nesting count went below MAX_SIGINTS. */
+ sigprocmask(0, NULL, &sigs);
+ for (i = 0; i < DM_ARRAY_SIZE(_ar_sigs); ++i)
+ if (_ar_sigs[i].oldmasked[_handler_installed]) {
+ sigaddset(&sigs, _ar_sigs[i].sig);
+ mask = 1;
+ }
+
+ if (mask && sigprocmask(SIG_SETMASK, &sigs, NULL))
+ log_sys_debug("sigprocmask", "SIG_SETMASK");
+
+ for (i = 0; i < DM_ARRAY_SIZE(_ar_sigs); ++i)
+ if (sigaction(_ar_sigs[i].sig, &_ar_sigs[i].oldhandler[_handler_installed], NULL))
+ log_sys_debug("sigaction", _ar_sigs[i].name);
+}
+
+void block_signals(uint32_t flags __attribute__((unused)))
+{
+ sigset_t set;
+
+ if (memlock_count_daemon())
+ return;
+
+ if (_signals_blocked)
+ return;
+
+ if (sigfillset(&set)) {
+ log_sys_error("sigfillset", "_block_signals");
+ return;
+ }
+
+ if (sigprocmask(SIG_SETMASK, &set, &_oldset)) {
+ log_sys_error("sigprocmask", "_block_signals");
+ return;
+ }
+
+ _signals_blocked = 1;
+}
+
+void unblock_signals(void)
+{
+ if (memlock_count_daemon())
+ return;
+
+ /* Don't unblock signals while any locks are held */
+ if (!_signals_blocked)
+ return;
+
+ if (sigprocmask(SIG_SETMASK, &_oldset, NULL)) {
+ log_sys_error("sigprocmask", "_block_signals");
+ return;
+ }
+
+ _signals_blocked = 0;
+}
+
+/* usleep with enabled signal handler.
+ * Returns 1 when there was interruption */
+int interruptible_usleep(useconds_t usec)
+{
+ int r;
+
+ sigint_allow();
+ r = usleep(usec);
+ sigint_restore();
+
+ return (sigint_caught() || r) ? 1 : 0;
+}
diff --git a/lib/misc/lvm-signal.h b/lib/misc/lvm-signal.h
new file mode 100644
index 0000000..a39f77e
--- /dev/null
+++ b/lib/misc/lvm-signal.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _LVM_SIGNAL_H
+#define _LVM_SIGNAL_H
+
+#include <unistd.h>
+
+void remove_ctrl_c_handler(void);
+void install_ctrl_c_handler(void);
+int init_signals(int suppress_messages);
+
+void sigint_allow(void);
+int sigint_caught(void);
+void sigint_restore(void);
+void sigint_clear(void);
+
+void block_signals(uint32_t flags);
+void unblock_signals(void);
+
+int interruptible_usleep(useconds_t usec);
+#endif
diff --git a/lib/misc/lvm-string.c b/lib/misc/lvm-string.c
index 7e4bbdd..959a6a1 100644
--- a/lib/misc/lvm-string.c
+++ b/lib/misc/lvm-string.c
@@ -10,13 +10,16 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "lib.h"
-#include "lvm-string.h"
+#include "lib/misc/lib.h"
+#include "lib/misc/lvm-string.h"
+#include "lib/metadata/metadata-exported.h"
+#include "lib/display/display.h"
#include <ctype.h>
+#include <stdarg.h>
int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
{
@@ -63,91 +66,254 @@ int validate_tag(const char *n)
return 1;
}
-/*
- * Device layer names are all of the form <vg>-<lv>-<layer>, any
- * other hyphens that appear in these names are quoted with yet
- * another hyphen. The top layer of any device has no layer
- * name. eg, vg0-lvol0.
- */
-int validate_name(const char *n)
+static name_error_t _validate_name(const char *n)
{
register char c;
register int len = 0;
if (!n || !*n)
- return 0;
+ return NAME_INVALID_EMPTY;
/* Hyphen used as VG-LV separator - ambiguity if LV starts with it */
if (*n == '-')
- return 0;
+ return NAME_INVALID_HYPHEN;
- if (!strcmp(n, ".") || !strcmp(n, ".."))
- return 0;
+ if ((*n == '.') && (!n[1] || (n[1] == '.' && !n[2]))) /* ".", ".." */
+ return NAME_INVALID_DOTS;
while ((len++, c = *n++))
if (!isalnum(c) && c != '.' && c != '_' && c != '-' && c != '+')
- return 0;
+ return NAME_INVALID_CHARSET;
if (len > NAME_LEN)
- return 0;
+ return NAME_INVALID_LENGTH;
- return 1;
+ return NAME_VALID;
}
-int apply_lvname_restrictions(const char *name)
+/*
+ * Device layer names are all of the form <vg>-<lv>-<layer>, any
+ * other hyphens that appear in these names are quoted with yet
+ * another hyphen. The top layer of any device has no layer
+ * name. eg, vg0-lvol0.
+ */
+int validate_name(const char *n)
{
- const char *reserved_prefixes[] = {
- "snapshot",
+ return (_validate_name(n) == NAME_VALID) ? 1 : 0;
+}
+
+/*
+ * Copy valid systemid characters from source to destination.
+ * Invalid characters are skipped. Copying is stopped
+ * when NAME_LEN characters have been copied.
+ * A terminating NUL is appended.
+ */
+void copy_systemid_chars(const char *src, char *dst)
+{
+ const char *s = src;
+ char *d = dst;
+ int len = 0;
+ char c;
+
+ if (!s || !*s)
+ return;
+
+ /* Skip non-alphanumeric starting characters */
+ while (*s && !isalnum(*s))
+ s++;
+
+ while ((c = *s++)) {
+ if (!isalnum(c) && c != '.' && c != '_' && c != '-' && c != '+')
+ continue;
+
+ *d++ = c;
+
+ if (++len >= NAME_LEN)
+ break;
+ }
+
+ *d = '\0';
+}
+
+static const char *_lvname_has_reserved_prefix(const char *lvname)
+{
+ static const char _prefixes[][12] = {
"pvmove",
- NULL
+ "snapshot"
};
+ unsigned i;
- const char *reserved_strings[] = {
- "_mlog",
+ for (i = 0; i < DM_ARRAY_SIZE(_prefixes); ++i)
+ if (!strncmp(lvname, _prefixes[i], strlen(_prefixes[i])))
+ return _prefixes[i];
+
+ return NULL;
+}
+
+static const char *_lvname_has_reserved_component_string(const char *lvname)
+{
+ static const char _strings[][12] = {
+ /* Suffixes for compoment LVs */
+ "_cdata",
+ "_cmeta",
+ "_corig",
+ "_cpool",
+ "_cvol",
+ "_wcorig",
"_mimage",
+ "_mlog",
"_rimage",
"_rmeta",
- "_vorigin",
"_tdata",
"_tmeta",
- NULL
+ "_vdata",
+ "_imeta",
+ "_iorig"
};
+ unsigned i;
+
+ for (i = 0; i < DM_ARRAY_SIZE(_strings); ++i)
+ if (strstr(lvname, _strings[i]))
+ return _strings[i];
+ return NULL;
+}
+
+static const char *_lvname_has_reserved_string(const char *lvname)
+{
+ static const char _strings[][12] = {
+ /* Additional suffixes for non-compoment LVs */
+ "_pmspare",
+ "_vorigin"
+ };
unsigned i;
+ const char *cs;
+
+ if ((cs = _lvname_has_reserved_component_string(lvname)))
+ return cs;
+
+ for (i = 0; i < DM_ARRAY_SIZE(_strings); ++i)
+ if (strstr(lvname, _strings[i]))
+ return _strings[i];
+
+ return NULL;
+}
+
+
+int apply_lvname_restrictions(const char *name)
+{
const char *s;
- for (i = 0; (s = reserved_prefixes[i]); i++) {
- if (!strncmp(name, s, strlen(s))) {
- log_error("Names starting \"%s\" are reserved. "
- "Please choose a different LV name.", s);
- return 0;
- }
+ if ((s = _lvname_has_reserved_prefix(name))) {
+ log_error("Names starting \"%s\" are reserved. "
+ "Please choose a different LV name.", s);
+ return 0;
}
- for (i = 0; (s = reserved_strings[i]); i++) {
- if (strstr(name, s)) {
- log_error("Names including \"%s\" are reserved. "
- "Please choose a different LV name.", s);
- return 0;
- }
+ if ((s = _lvname_has_reserved_string(name))) {
+ log_error("Names including \"%s\" are reserved. "
+ "Please choose a different LV name.", s);
+ return 0;
}
return 1;
}
-int is_reserved_lvname(const char *name)
+/*
+ * Validates name and returns an emunerated reason for name validataion failure.
+ */
+name_error_t validate_name_detailed(const char *name)
{
- int rc, old_suppress;
+ return _validate_name(name);
+}
- old_suppress = log_suppress(2);
- rc = !apply_lvname_restrictions(name);
- log_suppress(old_suppress);
+int is_reserved_lvname(const char *name)
+{
+ return (_lvname_has_reserved_prefix(name) ||
+ _lvname_has_reserved_string(name)) ? 1 : 0;
+}
- return rc;
+int is_component_lvname(const char *name)
+{
+ return (_lvname_has_reserved_component_string(name)) ? 1 : 0;
}
-char *build_dm_uuid(struct dm_pool *mem, const char *lvid,
+char *build_dm_uuid(struct dm_pool *mem, const struct logical_volume *lv,
const char *layer)
{
- return dm_build_dm_uuid(mem, UUID_PREFIX, lvid, layer);
+ const char *lvid = lv->lvid.s;
+ char *dlid;
+
+ if (!layer) {
+ /*
+ * Mark internal LVs with layer suffix
+ * so tools like blkid may immeditelly see it's
+ * an internal LV they should not scan.
+ * Should also make internal detection simpler.
+ */
+ /* Suffixes used here MUST match lib/activate/dev_manager.c */
+ layer = lv_is_cache_origin(lv) ? "real" :
+ lv_is_writecache_origin(lv) ? "real" :
+ (lv_is_cache(lv) && lv_is_pending_delete(lv)) ? "real" :
+ lv_is_cache_pool_data(lv) ? "cdata" :
+ lv_is_cache_pool_metadata(lv) ? "cmeta" :
+ lv_is_cache_vol(lv) ? "cvol" :
+ // FIXME: dm-tree needs fixes for mirrors/raids
+ //lv_is_mirror_image(lv) ? "mimage" :
+ //lv_is_mirror_log(lv) ? "mlog" :
+ //lv_is_raid_image(lv) ? "rimage" :
+ //lv_is_raid_metadata(lv) ? "rmeta" :
+ lv_is_thin_pool(lv) ? "pool" :
+ lv_is_thin_pool_data(lv) ? "tdata" :
+ lv_is_thin_pool_metadata(lv) ? "tmeta" :
+ lv_is_vdo_pool(lv) ? "pool" :
+ lv_is_vdo_pool_data(lv) ? "vdata" :
+ NULL;
+ }
+
+ if (!(dlid = dm_build_dm_uuid(mem, UUID_PREFIX, lvid, layer)))
+ log_error("Failed to build LVM dlid for %s.",
+ display_lvname(lv));
+
+ return dlid;
+}
+
+char *first_substring(const char *str, ...)
+{
+ char *substr, *r = NULL;
+ va_list ap;
+
+ va_start(ap, str);
+
+ while ((substr = va_arg(ap, char *)))
+ if ((r = strstr(str, substr)))
+ break;
+
+ va_end(ap);
+
+ return r;
+}
+
+/* Cut suffix (if present) and write the name into NAME_LEN sized new_name buffer
+ * When suffix is NULL, everythin past the last '_' is removed.
+ * Returns 1 when suffix was removed, 0 otherwise.
+ */
+int drop_lvname_suffix(char *new_name, const char *name, const char *suffix)
+{
+ char *c;
+
+ if (!dm_strncpy(new_name, name, NAME_LEN)) {
+ log_debug(INTERNAL_ERROR "Name is too long.");
+ return 0;
+ }
+
+ if (!(c = strrchr(new_name, '_')))
+ return 0;
+
+ if (suffix && strcmp(c + 1, suffix))
+ return 0;
+
+ *c = 0; /* remove suffix */
+
+ return 1;
}
diff --git a/lib/misc/lvm-string.h b/lib/misc/lvm-string.h
index 6be048d..5d2f95a 100644
--- a/lib/misc/lvm-string.h
+++ b/lib/misc/lvm-string.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -10,30 +10,53 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_STRING_H
#define _LVM_STRING_H
-#include <stdio.h>
-#include <stdarg.h>
-
#define NAME_LEN 128
#define UUID_PREFIX "LVM-"
+#include <sys/types.h>
+
+struct dm_pool;
struct pool;
+struct logical_volume;
+
+typedef enum name_error {
+ NAME_VALID = 0,
+ NAME_INVALID_EMPTY = -1,
+ NAME_INVALID_HYPHEN = -2,
+ NAME_INVALID_DOTS = -3,
+ NAME_INVALID_CHARSET = -4,
+ NAME_INVALID_LENGTH = -5
+} name_error_t;
int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
__attribute__ ((format(printf, 3, 4)));
-char *build_dm_uuid(struct dm_pool *mem, const char *lvid,
+char *build_dm_uuid(struct dm_pool *mem, const struct logical_volume *lvid,
const char *layer);
int validate_name(const char *n);
+name_error_t validate_name_detailed(const char *n);
int validate_tag(const char *n);
+void copy_systemid_chars(const char *src, char *dst);
+
int apply_lvname_restrictions(const char *name);
+int is_component_lvname(const char *name);
int is_reserved_lvname(const char *name);
+/*
+ * Provided with a NULL-terminated argument list of const char *
+ * substrings that might be contained within the string str, use
+ * strstr() to search str for each in turn and return a pointer to the
+ * first match or else NULL.
+ */
+char *first_substring(const char *str, ...);
+int drop_lvname_suffix(char *new_name, const char *name, const char *suffix);
+
#endif
diff --git a/lib/misc/lvm-version.h.in b/lib/misc/lvm-version.h.in
deleted file mode 100644
index 2574890..0000000
--- a/lib/misc/lvm-version.h.in
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
- *
- * This file is part of LVM2.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _LVM_VERSION_H
-/**
- * The LVM version number
- *
- * LVM_MAJOR.LVM_MINOR.LVM_PATCHLEVEL(LVM_LIBAPI)[-LVM_RELEASE]
- */
-
-#define LVM_VERSION @LVM_VERSION@
-#define LVM_MAJOR @LVM_MAJOR@
-#define LVM_MINOR @LVM_MINOR@
-#define LVM_PATCHLEVEL @LVM_PATCHLEVEL@
-#define LVM_LIBAPI @LVM_LIBAPI@
-#define LVM_RELEASE @LVM_RELEASE@
-#define LVM_RELEASE_DATE @LVM_RELEASE_DATE@
-#endif
diff --git a/lib/misc/lvm-wrappers.c b/lib/misc/lvm-wrappers.c
index 6cffae3..2e0cfd5 100644
--- a/lib/misc/lvm-wrappers.c
+++ b/lib/misc/lvm-wrappers.c
@@ -9,34 +9,45 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "lib.h"
+#include "lib/misc/lib.h"
#include <unistd.h>
#include <fcntl.h>
#ifdef UDEV_SYNC_SUPPORT
-static const char _no_context_msg[] = "Udev library context not set.";
+#include <libudev.h>
+
struct udev *_udev;
int udev_init_library_context(void)
{
if (_udev)
- udev_unref(_udev);
+ return 1;
+
+ if (getenv("DM_DISABLE_UDEV"))
+ return 0;
if (!(_udev = udev_new())) {
log_error("Failed to create udev library context.");
return 0;
}
+ if (!udev_is_running()) {
+ udev_unref(_udev);
+ _udev = NULL;
+ return 0;
+ }
+
return 1;
}
void udev_fin_library_context(void)
{
- udev_unref(_udev);
+ if (_udev)
+ udev_unref(_udev);
_udev = NULL;
}
@@ -46,12 +57,12 @@ int udev_is_running(void)
int r;
if (!_udev) {
- log_debug(_no_context_msg);
+ log_debug_activation("Udev library context not set.");
goto bad;
}
if (!(udev_queue = udev_queue_new(_udev))) {
- log_debug("Could not get udev state.");
+ log_debug_activation("Could not get udev state.");
goto bad;
}
@@ -61,11 +72,11 @@ int udev_is_running(void)
return r;
bad:
- log_debug("Assuming udev is not running.");
+ log_debug_activation("Assuming udev is not running.");
return 0;
}
-struct udev* udev_get_library_context(void)
+void *udev_get_library_context(void)
{
return _udev;
}
@@ -77,6 +88,11 @@ int udev_init_library_context(void)
return 1;
}
+void *udev_get_library_context(void)
+{
+ return NULL;
+}
+
void udev_fin_library_context(void)
{
}
@@ -117,3 +133,42 @@ int read_urandom(void *buf, size_t len)
return 1;
}
+/*
+ * Return random integer in [0,max) interval
+ *
+ * The loop rejects numbers that come from an "incomplete" slice of the
+ * RAND_MAX space. Considering the number space [0, RAND_MAX] is divided
+ * into some "max"-sized slices and at most a single smaller slice,
+ * between [n*max, RAND_MAX] for suitable n, numbers from this last slice
+ * are discarded because they could distort the distribution in favour of
+ * smaller numbers.
+ */
+unsigned lvm_even_rand(unsigned *seed, unsigned max)
+{
+ unsigned r, ret;
+
+ do {
+ r = (unsigned) rand_r(seed);
+ ret = r % max;
+ } while (r - ret > RAND_MAX - max);
+
+ return ret;
+}
+
+int clvmd_is_running(void)
+{
+#ifdef CLVMD_PIDFILE
+ return dm_daemon_is_running(CLVMD_PIDFILE);
+#else
+ return 0;
+#endif
+}
+
+int cmirrord_is_running(void)
+{
+#ifdef CMIRRORD_PIDFILE
+ return dm_daemon_is_running(CMIRRORD_PIDFILE);
+#else
+ return 0;
+#endif
+}
diff --git a/lib/misc/lvm-wrappers.h b/lib/misc/lvm-wrappers.h
index e43f831..3c45aff 100644
--- a/lib/misc/lvm-wrappers.h
+++ b/lib/misc/lvm-wrappers.h
@@ -10,18 +10,14 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_WRAPPERS_H
#define _LVM_WRAPPERS_H
-#ifdef UDEV_SYNC_SUPPORT
-#include <libudev.h>
-struct udev *udev_get_library_context(void);
-#endif
-
int udev_init_library_context(void);
+void *udev_get_library_context(void);
void udev_fin_library_context(void);
int udev_is_running(void);
@@ -32,19 +28,13 @@ int lvm_getpagesize(void);
*/
int read_urandom(void *buf, size_t len);
-# ifndef HAVE_SIGINTERRUPT
-# define siginterrupt(sig, flag) \
- do { \
- int ret; \
- struct sigaction act; \
- (void) sigaction(sig, NULL, &act); \
- if (flag) \
- act.sa_flags &= SA_RESTART; \
- else \
- act.sa_flags |= SA_RESTART; \
- ret = sigaction(sig, &act, NULL); \
- return ret; \
- while (0)
-# endif
+/*
+ * Return random integer in [0,max) interval
+ */
+unsigned lvm_even_rand(unsigned *seed, unsigned max);
+
+int clvmd_is_running(void);
+int cmirrord_is_running(void);
+
#endif
diff --git a/lib/misc/sharedlib.c b/lib/misc/sharedlib.c
index 4c2d178..544bb5f 100644
--- a/lib/misc/sharedlib.c
+++ b/lib/misc/sharedlib.c
@@ -10,12 +10,13 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "lib.h"
-#include "config.h"
+#include "lib/misc/lib.h"
#include "sharedlib.h"
+#include "lib/config/config.h"
+#include "lib/commands/toolcontext.h"
#include <limits.h>
#include <sys/stat.h>
@@ -25,43 +26,17 @@ void get_shared_library_path(struct cmd_context *cmd, const char *libname,
char *path, size_t path_len)
{
struct stat info;
- const char *lib_dir;
+
+ if (!path_len)
+ return;
/* If libname doesn't begin with '/' then use lib_dir/libname,
* if present */
if (libname[0] == '/' ||
- !(lib_dir = find_config_tree_str(cmd, "global/library_dir", 0)) ||
- (dm_snprintf(path, path_len, "%s/%s", lib_dir,
+ (!cmd->lib_dir &&
+ !(cmd->lib_dir = find_config_tree_str(cmd, global_library_dir_CFG, NULL))) ||
+ (dm_snprintf(path, path_len, "%s/%s", cmd->lib_dir,
libname) == -1) || stat(path, &info) == -1) {
- strncpy(path, libname, path_len - 1);
- path[path_len - 1] = '\0';
- }
-}
-
-void *load_shared_library(struct cmd_context *cmd, const char *libname,
- const char *desc, int silent)
-{
- char path[PATH_MAX];
- void *library;
-
- if (is_static()) {
- log_error("Not loading shared %s library %s in static mode.",
- desc, libname);
- return NULL;
+ (void) dm_strncpy(path, libname, path_len);
}
-
- get_shared_library_path(cmd, libname, path, sizeof(path));
-
- log_very_verbose("Opening shared %s library %s", desc, path);
-
- if (!(library = dlopen(path, RTLD_LAZY | RTLD_GLOBAL))) {
- if (silent && ignorelockingfailure())
- log_verbose("Unable to open external %s library %s: %s",
- desc, path, dlerror());
- else
- log_error("Unable to open external %s library %s: %s",
- desc, path, dlerror());
- }
-
- return library;
}
diff --git a/lib/misc/sharedlib.h b/lib/misc/sharedlib.h
index d996a8b..23f2acc 100644
--- a/lib/misc/sharedlib.h
+++ b/lib/misc/sharedlib.h
@@ -10,18 +10,15 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_SHAREDLIB_H
#define _LVM_SHAREDLIB_H
-#include "config.h"
+#include "lib/config/config.h"
#include <dlfcn.h>
void get_shared_library_path(struct cmd_context *cmd, const char *libname,
char *path, size_t path_len);
-void *load_shared_library(struct cmd_context *cmd, const char *libname,
- const char *what, int silent);
-
#endif
diff --git a/lib/misc/timestamp.c b/lib/misc/timestamp.c
deleted file mode 100644
index 47b5586..0000000
--- a/lib/misc/timestamp.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2006 Rackable Systems All rights reserved.
- *
- * This file is part of LVM2.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Abstract out the time methods used so they can be adjusted later -
- * the results of these routines should stay in-core. This implementation
- * requires librt.
- */
-
-#include "lib.h"
-#include <stdlib.h>
-
-#include "timestamp.h"
-
-/*
- * The realtime section uses clock_gettime with the CLOCK_MONOTONIC
- * parameter to prevent issues with time warps
- */
-#ifdef HAVE_REALTIME
-
-#include <time.h>
-#include <bits/time.h>
-
-struct timestamp {
- struct timespec t;
-};
-
-struct timestamp *get_timestamp(void)
-{
- struct timestamp *ts = NULL;
-
- if (!(ts = dm_malloc(sizeof(*ts))))
- return_NULL;
-
- if (clock_gettime(CLOCK_MONOTONIC, &ts->t)) {
- log_sys_error("clock_gettime", "get_timestamp");
- return NULL;
- }
-
- return ts;
-}
-
-/* cmp_timestamp: Compare two timestamps
- *
- * Return: -1 if t1 is less than t2
- * 0 if t1 is equal to t2
- * 1 if t1 is greater than t2
- */
-int cmp_timestamp(struct timestamp *t1, struct timestamp *t2)
-{
- if(t1->t.tv_sec < t2->t.tv_sec)
- return -1;
- if(t1->t.tv_sec > t2->t.tv_sec)
- return 1;
-
- if(t1->t.tv_nsec < t2->t.tv_nsec)
- return -1;
- if(t1->t.tv_nsec > t2->t.tv_nsec)
- return 1;
-
- return 0;
-}
-
-#else /* ! HAVE_REALTIME */
-
-/*
- * The !realtime section just uses gettimeofday and is therefore subject
- * to ntp-type time warps - not sure if should allow that.
- */
-
-#include <sys/time.h>
-
-struct timestamp {
- struct timeval t;
-};
-
-struct timestamp *get_timestamp(void)
-{
- struct timestamp *ts = NULL;
-
- if (!(ts = dm_malloc(sizeof(*ts))))
- return_NULL;
-
- if (gettimeofday(&ts->t, NULL)) {
- log_sys_error("gettimeofday", "get_timestamp");
- return NULL;
- }
-
- return ts;
-}
-
-/* cmp_timestamp: Compare two timestamps
- *
- * Return: -1 if t1 is less than t2
- * 0 if t1 is equal to t2
- * 1 if t1 is greater than t2
- */
-int cmp_timestamp(struct timestamp *t1, struct timestamp *t2)
-{
- if(t1->t.tv_sec < t2->t.tv_sec)
- return -1;
- if(t1->t.tv_sec > t2->t.tv_sec)
- return 1;
-
- if(t1->t.tv_usec < t2->t.tv_usec)
- return -1;
- if(t1->t.tv_usec > t2->t.tv_usec)
- return 1;
-
- return 0;
-}
-
-#endif /* HAVE_REALTIME */
-
-void destroy_timestamp(struct timestamp *t)
-{
- dm_free(t);
-}
diff --git a/lib/misc/timestamp.h b/lib/misc/timestamp.h
deleted file mode 100644
index 50e2a85..0000000
--- a/lib/misc/timestamp.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2006 Rackable Systems All rights reserved.
- *
- * This file is part of LVM2.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _LVM_TIMESTAMP_H
-#define _LVM_TIMESTAMP_H
-
-struct timestamp;
-
-struct timestamp *get_timestamp(void);
-
-/* cmp_timestamp: Compare two timestamps
- *
- * Return: -1 if t1 is less than t2
- * 0 if t1 is equal to t2
- * 1 if t1 is greater than t2
- */
-int cmp_timestamp(struct timestamp *t1, struct timestamp *t2);
-
-void destroy_timestamp(struct timestamp *t);
-
-#endif /* _LVM_TIMESTAMP_H */
-
diff --git a/lib/misc/util.h b/lib/misc/util.h
index a453469..35514ee 100644
--- a/lib/misc/util.h
+++ b/lib/misc/util.h
@@ -9,12 +9,14 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_UTIL_H
#define _LVM_UTIL_H
+#include <inttypes.h>
+
#define min(a, b) ({ typeof(a) _a = (a); \
typeof(b) _b = (b); \
(void) (&_a == &_b); \
@@ -25,12 +27,115 @@
(void) (&_a == &_b); \
_a > _b ? _a : _b; })
+#define is_power_of_2(n) ((n) && !((n) & ((n) - 1)))
+
#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6)
#define uninitialized_var(x) x
#else
#define uninitialized_var(x) x = x
#endif
+/*
+ * GCC 3.4 adds a __builtin_clz, which uses the count leading zeros (clz)
+ * instruction on arches that have one. Provide a fallback using shifts
+ * and comparisons for older compilers.
+ */
+#ifdef HAVE___BUILTIN_CLZ
+#define clz(x) __builtin_clz((x))
+#else /* ifdef HAVE___BUILTIN_CLZ */
+static unsigned _dm_clz(unsigned x)
+{
+ int n;
+
+ if ((int)x <= 0) return (~x >> 26) & 32;
+
+ n = 1;
+
+ if ((x >> 16) == 0) {
+ n = n + 16;
+ x = x << 16;
+ }
+
+ if ((x >> 24) == 0) {
+ n = n + 8;
+ x = x << 8;
+ }
+
+ if ((x >> 28) == 0) {
+ n = n + 4;
+ x = x << 4;
+ }
+
+ if ((x >> 30) == 0) {
+ n = n + 2;
+ x = x << 2;
+ }
+ n = n - (x >> 31);
+ return n;
+}
+#define clz(x) _dm_clz((x))
+#endif /* ifdef HAVE___BUILTIN_CLZ */
+
+#ifdef HAVE___BUILTIN_CLZLL
+#define clzll(x) __builtin_clzll((x))
+#else /* ifdef HAVE___BUILTIN_CLZ */
+static unsigned _dm_clzll(unsigned long long x)
+{
+ if (x <= 0xffffffff)
+ return 32 + clz((unsigned) (x & 0xffffffff));
+
+ return clz(x >> 32);
+}
+#define clzll(x) _dm_clzll((x))
+#endif /* ifdef HAVE___BUILTIN_CLZLL */
+
+#ifndef HAVE_FFS
+#ifdef HAVE___BUILTIN_FFS
+#define ffs(x) __builtin_ffs((x))
+#else
+#error ffs() not implemented!
+#endif /* ifdef HAVE___BUILTIN_FFS */
+#endif /* ifndef HAVE_FFS */
+
#define KERNEL_VERSION(major, minor, release) (((major) << 16) + ((minor) << 8) + (release))
+/* Define some portable printing types */
+#define PRIsize_t "zu"
+#define PRIssize_t "zd"
+#define PRIptrdiff_t "td"
+#define PRIpid_t PRId32
+
+/* For convenience */
+#define FMTsize_t "%" PRIsize_t
+#define FMTssize_t "%" PRIssize_t
+#define FMTptrdiff_t "%" PRIptrdiff_t
+#define FMTpid_t "%" PRIpid_t
+
+#define FMTd8 "%" PRId8
+#define FMTd16 "%" PRId16
+#define FMTd32 "%" PRId32
+#define FMTd64 "%" PRId64
+
+#define FMTi8 "%" PRIi8
+#define FMTi16 "%" PRIi16
+#define FMTi32 "%" PRIi32
+#define FMTi64 "%" PRIi64
+
+#define FMTo8 "%" PRIo8
+#define FMTo16 "%" PRIo16
+#define FMTo32 "%" PRIo32
+#define FMTo64 "%" PRIo64
+
+#define FMTu8 "%" PRIu8
+#define FMTu16 "%" PRIu16
+#define FMTu32 "%" PRIu32
+#define FMTu64 "%" PRIu64
+
+#define FMTx8 "%" PRIx8
+#define FMTx16 "%" PRIx16
+#define FMTx32 "%" PRIx32
+#define FMTx64 "%" PRIx64
+
+#define FMTVGID "%." DM_TO_STRING(ID_LEN) "s"
+
#endif