diff options
author | Karol Lewandowski <k.lewandowsk@samsung.com> | 2024-01-23 12:58:00 +0100 |
---|---|---|
committer | Karol Lewandowski <k.lewandowsk@samsung.com> | 2024-01-23 12:58:00 +0100 |
commit | cbab226a74fbaaa43220dee80e8435555c6506ce (patch) | |
tree | 1bbd14ec625ea85d0bcc32232d51c1f71e2604d2 /lib/misc | |
parent | 44a3c2255bc480c82f34db156553a595606d8a0b (diff) | |
download | device-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 |
Imported Upstream version 2.03.22upstream/libdevmapper-1.02.196upstream/2.03.22upstreamsandbox/klewandowski/upstream_2.03.22
Diffstat (limited to 'lib/misc')
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 |