Version 1.00.20 -
=============================
+ Attempt to fix /dev/mapper/control transparently if it's wrong.
Configuration-time option for setting uid/gid/mode for /dev/mapper nodes.
Update kernel patches for 2.4.27/2.4.28-pre-4 (includes minor fixes).
Add --noheadings columns option for colon-separated dmsetup output.
../lib/libdevmapper.h
+../lib/libdm-file.h
../po/pogen.h
--- /dev/null
+/*
+ * Copyright (C) 2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * 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 General Public License v.2.
+ *
+ * You should have received a copy of the GNU 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_INTL_H
+#define _LVM_INTL_H
+
+#ifdef INTL_PACKAGE
+# include <libintl.h>
+# define _(String) dgettext(INTL_PACKAGE, (String))
+#else
+# define _(String) (String)
+#endif
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * 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 General Public License v.2.
+ *
+ * You should have received a copy of the GNU 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
+ */
+
+/*
+ * This file must be included first by every library source file.
+ */
+#ifndef _LVM_LIB_H
+#define _LVM_LIB_H
+
+#define _REENTRANT
+#define _GNU_SOURCE
+#define _FILE_OFFSET_BITS 64
+
+#include "log.h"
+#include "intl.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#endif
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
-# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
#
# This file is part of the device-mapper userspace tools.
#
VPATH = @srcdir@
interface = @interface@
-SOURCES = libdm-common.c $(interface)/libdm-iface.c
+SOURCES = libdm-common.c libdm-file.c $(interface)/libdm-iface.c
INCLUDES = -I$(interface)
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "lib.h"
#include "libdm-targets.h"
#include "libdm-common.h"
-#include "log.h"
+#include "libdm-file.h"
#ifdef DM_COMPAT
# include "libdm-compat.h"
#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
-#include <errno.h>
-#include <sys/stat.h>
#include <sys/ioctl.h>
#include <limits.h>
#error The version of dm-ioctl.h included is incompatible.
#endif
+/* FIXME This should be exported in device-mapper.h */
+#define DM_NAME "device-mapper"
+
+#define PROC_MISC "/proc/misc"
+#define PROC_DEVICES "/proc/devices"
+#define MISC_NAME "misc"
+
/* dm major version no for running kernel */
static int _dm_version = DM_VERSION_MAJOR;
static int _log_suppress = 0;
return (void *) (((unsigned long) ptr + agn) & ~agn);
}
+static int _get_proc_number(const char *file, const char *name,
+ uint32_t *number)
+{
+ FILE *fl;
+ char nm[256];
+ int c;
+
+ if (!(fl = fopen(file, "r"))) {
+ log_error("%s: fopen failed: %s", file, strerror(errno));
+ return 0;
+ }
+
+ while (!feof(fl)) {
+ if (fscanf(fl, "%d %255s\n", number, &nm[0]) == 2) {
+ if (!strcmp(name, nm)) {
+ fclose(fl);
+ return 1;
+ }
+ }
+ do {
+ c = fgetc(fl);
+ } while (c != EOF && c != '\n');
+ }
+ fclose(fl);
+
+ log_error("%s: No entry for %s found", file, name);
+ return 0;
+}
+
+static int _control_device_number(uint32_t *major, uint32_t *minor)
+{
+ if (!_get_proc_number(PROC_DEVICES, MISC_NAME, major) ||
+ !_get_proc_number(PROC_MISC, DM_NAME, minor)) {
+ *major = 0;
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Returns 1 if exists; 0 if it doesn't; -1 if it's wrong
+ */
+static int _control_exists(const char *control, uint32_t major, uint32_t minor)
+{
+ struct stat buf;
+
+ if (stat(control, &buf) < 0) {
+ if (errno != ENOENT)
+ log_error("%s: stat failed: %s", control,
+ strerror(errno));
+ return 0;
+ }
+
+ if (!S_ISCHR(buf.st_mode)) {
+ log_verbose("%s: Wrong inode type", control);
+ if (!unlink(control))
+ return 0;
+ log_error("%s: unlink failed: %s", control,
+ strerror(errno));
+ return -1;
+ }
+
+ if (major && buf.st_rdev != MKDEV(major, minor)) {
+ log_verbose("%s: Wrong device number: (%u, %u) instead of "
+ "(%u, %u)", control,
+ MAJOR(buf.st_mode), MINOR(buf.st_mode),
+ major, minor);
+ if (!unlink(control))
+ return 0;
+ log_error("%s: unlink failed: %s", control,
+ strerror(errno));
+ return -1;
+ }
+
+ return 1;
+}
+
+static int _create_control(const char *control, uint32_t major, uint32_t minor)
+{
+ int ret;
+ mode_t old_umask;
+
+ if (!major)
+ return 0;
+
+ old_umask = umask(0022);
+ ret = create_dir(dm_dir());
+ umask(old_umask);
+
+ if (!ret)
+ return 0;
+
+ log_verbose("Creating device %s (%u, %u)", control, major, minor);
+
+ if (mknod(control, S_IFCHR | S_IRUSR | S_IWUSR,
+ MKDEV(major, minor)) < 0) {
+ log_error("%s: mknod failed: %s", control, strerror(errno));
+ return 0;
+ }
+
+#ifdef HAVE_SELINUX
+ if (!set_selinux_context(control)) {
+ stack;
+ return 0;
+ }
+#endif
+
+ return 1;
+}
+
static int _open_control(void)
{
char control[PATH_MAX];
+ uint32_t major = 0, minor;
if (_control_fd != -1)
return 1;
snprintf(control, sizeof(control), "%s/control", dm_dir());
+ if (!_control_device_number(&major, &minor))
+ log_error("Is device-mapper driver missing from kernel?");
+
+ if (!_control_exists(control, major, minor) &&
+ !_create_control(control, major, minor))
+ goto error;
+
if ((_control_fd = open(control, O_RDWR)) < 0) {
log_error("%s: open failed: %s", control, strerror(errno));
- log_error("Is device-mapper driver missing from kernel?");
- return 0;
+ goto error;
}
return 1;
+
+error:
+ log_error("Failure to communicate with kernel device-mapper driver.");
+ return 0;
}
void dm_task_destroy(struct dm_task *dmt)
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "lib.h"
#include "libdm-targets.h"
#include "libdm-common.h"
#include "list.h"
-#include "log.h"
#include "kdev_t.h"
-#include <stdio.h>
-#include <stdlib.h>
#include <stdarg.h>
-#include <string.h>
#include <sys/param.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
#include <linux/dm-ioctl.h>
#ifdef HAVE_SELINUX
{
struct dm_task *dmt = malloc(sizeof(*dmt));
- if (!dm_check_version())
- return NULL;
-
if (!dmt) {
log_error("dm_task_create: malloc(%d) failed", sizeof(*dmt));
return NULL;
}
+ if (!dm_check_version())
+ return NULL;
+
memset(dmt, 0, sizeof(*dmt));
dmt->type = type;
}
#ifdef HAVE_SELINUX
-static int _set_selinux_context(const char *path)
+int set_selinux_context(const char *path)
{
security_context_t scontext;
}
#ifdef HAVE_SELINUX
- if (!_set_selinux_context(path))
+ if (!set_selinux_context(path))
return 0;
#endif
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
int rename_dev_node(const char *old_name, const char *new_name);
void update_devs(void);
+int set_selinux_context(const char *path);
+
#define DM_LIB_VERSION @DM_LIB_VERSION@
#endif
--- /dev/null
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * 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 General Public License v.2.
+ *
+ * You should have received a copy of the GNU 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
+ */
+
+#include "lib.h"
+#include "libdm-file.h"
+
+#include <sys/file.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <malloc.h>
+
+static int _create_dir_recursive(const char *dir)
+{
+ char *orig, *s;
+ int rc;
+
+ log_verbose("Creating directory \"%s\"", dir);
+ /* Create parent directories */
+ orig = s = strdup(dir);
+ while ((s = strchr(s, '/')) != NULL) {
+ *s = '\0';
+ if (*orig) {
+ rc = mkdir(orig, 0777);
+ if (rc < 0 && errno != EEXIST) {
+ log_error("%s: mkdir failed: %s", orig,
+ strerror(errno));
+ free(orig);
+ return 0;
+ }
+ }
+ *s++ = '/';
+ }
+ free(orig);
+
+ /* Create final directory */
+ rc = mkdir(dir, 0777);
+ if (rc < 0 && errno != EEXIST) {
+ log_error("%s: mkdir failed: %s", orig,
+ strerror(errno));
+ return 0;
+ }
+ return 1;
+}
+
+int create_dir(const char *dir)
+{
+ struct stat info;
+
+ if (!*dir)
+ return 1;
+
+ if (stat(dir, &info) < 0)
+ return _create_dir_recursive(dir);
+
+ if (S_ISDIR(info.st_mode))
+ return 1;
+
+ log_error("Directory \"%s\" not found", dir);
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * 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 General Public License v.2.
+ *
+ * You should have received a copy of the GNU 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 LIB_DMFILE_H
+#define LIB_DMFILE_H
+
+/*
+ * Create directory (recursively) if necessary. Return 1
+ * if directory was successfully created (or already exists), else 0.
+ */
+int create_dir(const char *dir);
+
+#endif