You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
363 lines
10 KiB
363 lines
10 KiB
14 years ago
|
From 571dbc5784af042c94ed0f025c4d2d842c591d1f Mon Sep 17 00:00:00 2001
|
||
|
From: =?utf8?q?Jean-Pierre=20Andr=C3=A9?= <jpandre@users.sourceforge.net>
|
||
|
Date: Tue, 5 Jul 2011 12:17:12 +0200
|
||
|
Subject: [PATCH] Fixed device path canonicalization for use by devmapper (basilinya)
|
||
|
|
||
|
For some reason, when the monted device is "/dev/mapper/*", a record
|
||
|
in the form "/dev/dm-*" ends up in /etc/mtab and the device cannot be
|
||
|
unmounted.
|
||
|
|
||
|
The reason is unclear, the /dev/mapper name is not a symlink, and the
|
||
|
function doing the name change is not known. No detailed feedback from
|
||
|
the users having met the issue.
|
||
|
|
||
|
The patch changes the name back to the /dev/mapper name after realpath()
|
||
|
is called, and, if there is an actual change, both the name passed to
|
||
|
ntfs-3g and the one passed to fuse and mount are logged in the hope
|
||
|
of getting a clue about what is happening.
|
||
|
|
||
|
But ntfs-3g is probably not the right place for a fix.
|
||
|
---
|
||
|
include/ntfs-3g/Makefile.am | 1 +
|
||
|
include/ntfs-3g/param.h | 5 ++
|
||
|
include/ntfs-3g/realpath.h | 24 ++++++++++
|
||
|
libntfs-3g/Makefile.am | 1 +
|
||
|
libntfs-3g/realpath.c | 103 +++++++++++++++++++++++++++++++++++++++++++
|
||
|
libntfs-3g/volume.c | 17 +------
|
||
|
src/lowntfs-3g.c | 13 +----
|
||
|
src/ntfs-3g.c | 13 +----
|
||
|
src/ntfs-3g_common.c | 5 ++-
|
||
|
src/ntfs-3g_common.h | 1 +
|
||
|
10 files changed, 148 insertions(+), 35 deletions(-)
|
||
|
create mode 100644 include/ntfs-3g/realpath.h
|
||
|
create mode 100644 libntfs-3g/realpath.c
|
||
|
|
||
|
diff --git a/include/ntfs-3g/Makefile.am b/include/ntfs-3g/Makefile.am
|
||
|
index 6067346..33343df 100644
|
||
|
--- a/include/ntfs-3g/Makefile.am
|
||
|
+++ b/include/ntfs-3g/Makefile.am
|
||
|
@@ -29,6 +29,7 @@ headers = \
|
||
|
ntfstime.h \
|
||
|
object_id.h \
|
||
|
param.h \
|
||
|
+ realpath.h \
|
||
|
reparse.h \
|
||
|
runlist.h \
|
||
|
security.h \
|
||
|
diff --git a/include/ntfs-3g/param.h b/include/ntfs-3g/param.h
|
||
|
index 57d122e..985fdb7 100644
|
||
|
--- a/include/ntfs-3g/param.h
|
||
|
+++ b/include/ntfs-3g/param.h
|
||
|
@@ -63,6 +63,11 @@ enum {
|
||
|
|
||
|
#define XATTRMAPPINGFILE ".NTFS-3G/XattrMapping" /* default mapping file */
|
||
|
|
||
|
+/*
|
||
|
+ * Parameters for path canonicalization
|
||
|
+ */
|
||
|
+
|
||
|
+#define MAPPERNAMELTH 256
|
||
|
|
||
|
/*
|
||
|
* Permission checking modes for high level and low level
|
||
|
diff --git a/include/ntfs-3g/realpath.h b/include/ntfs-3g/realpath.h
|
||
|
new file mode 100644
|
||
|
index 0000000..970d2af
|
||
|
--- /dev/null
|
||
|
+++ b/include/ntfs-3g/realpath.h
|
||
|
@@ -0,0 +1,24 @@
|
||
|
+/*
|
||
|
+ * realpath.h - realpath() aware of device mapper
|
||
|
+ */
|
||
|
+
|
||
|
+#ifndef REALPATH_H
|
||
|
+#define REALPATH_H
|
||
|
+
|
||
|
+#ifdef HAVE_CONFIG_H
|
||
|
+#include "config.h"
|
||
|
+#endif
|
||
|
+
|
||
|
+#ifdef HAVE_REALPATH
|
||
|
+#define ntfs_realpath realpath
|
||
|
+#else
|
||
|
+extern char *ntfs_realpath(const char *path, char *resolved_path);
|
||
|
+#endif
|
||
|
+
|
||
|
+#ifdef linux
|
||
|
+extern char *ntfs_realpath_canonicalize(const char *path, char *resolved_path);
|
||
|
+#else
|
||
|
+#define ntfs_realpath_canonicalize ntfs_realpath
|
||
|
+#endif
|
||
|
+
|
||
|
+#endif /* REALPATH_H */
|
||
|
diff --git a/libntfs-3g/Makefile.am b/libntfs-3g/Makefile.am
|
||
|
index 292233a..b84cf64 100644
|
||
|
--- a/libntfs-3g/Makefile.am
|
||
|
+++ b/libntfs-3g/Makefile.am
|
||
|
@@ -36,6 +36,7 @@ libntfs_3g_la_SOURCES = \
|
||
|
misc.c \
|
||
|
mst.c \
|
||
|
object_id.c \
|
||
|
+ realpath.c \
|
||
|
reparse.c \
|
||
|
runlist.c \
|
||
|
security.c \
|
||
|
diff --git a/libntfs-3g/realpath.c b/libntfs-3g/realpath.c
|
||
|
new file mode 100644
|
||
|
index 0000000..a93bc69
|
||
|
--- /dev/null
|
||
|
+++ b/libntfs-3g/realpath.c
|
||
|
@@ -0,0 +1,103 @@
|
||
|
+/*
|
||
|
+ * realpath.c - realpath() aware of device mapper
|
||
|
+ * Originated from the util-linux project.
|
||
|
+ */
|
||
|
+
|
||
|
+#ifdef HAVE_CONFIG_H
|
||
|
+#include "config.h"
|
||
|
+#endif
|
||
|
+
|
||
|
+#include <stdlib.h>
|
||
|
+#include <stdio.h>
|
||
|
+#include <string.h>
|
||
|
+
|
||
|
+#ifdef HAVE_LIMITS_H
|
||
|
+#include <limits.h>
|
||
|
+#endif
|
||
|
+#ifdef HAVE_CTYPE_H
|
||
|
+#include <ctype.h>
|
||
|
+#endif
|
||
|
+
|
||
|
+#include "param.h"
|
||
|
+#include "realpath.h"
|
||
|
+
|
||
|
+/* If there is no realpath() on the system, provide a dummy one. */
|
||
|
+#ifndef HAVE_REALPATH
|
||
|
+char *ntfs_realpath(const char *path, char *resolved_path)
|
||
|
+{
|
||
|
+ strncpy(resolved_path, path, PATH_MAX);
|
||
|
+ resolved_path[PATH_MAX] = '\0';
|
||
|
+ return resolved_path;
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
+
|
||
|
+#ifdef linux
|
||
|
+
|
||
|
+/*
|
||
|
+ * Converts private "dm-N" names to "/dev/mapper/<name>"
|
||
|
+ *
|
||
|
+ * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
|
||
|
+ * provides the real DM device names in /sys/block/<ptname>/dm/name
|
||
|
+ */
|
||
|
+static char *
|
||
|
+canonicalize_dm_name(const char *ptname, char *canonical)
|
||
|
+{
|
||
|
+ FILE *f;
|
||
|
+ size_t sz;
|
||
|
+ char path[MAPPERNAMELTH + 24];
|
||
|
+ char name[MAPPERNAMELTH + 16];
|
||
|
+ char *res = NULL;
|
||
|
+
|
||
|
+ snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
|
||
|
+ if (!(f = fopen(path, "r")))
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ /* read "<name>\n" from sysfs */
|
||
|
+ if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
|
||
|
+ name[sz - 1] = '\0';
|
||
|
+ snprintf(path, sizeof(path), "/dev/mapper/%s", name);
|
||
|
+ res = strcpy(canonical, path);
|
||
|
+ }
|
||
|
+ fclose(f);
|
||
|
+ return res;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * Canonicalize a device path
|
||
|
+ *
|
||
|
+ * Workaround from "basinilya" for fixing device mapper paths.
|
||
|
+ *
|
||
|
+ * Background (Phillip Susi, 2011-04-09)
|
||
|
+ * - ntfs-3g canonicalizes the device name so that if you mount with
|
||
|
+ * /dev/mapper/foo, the device name listed in mtab is /dev/dm-n,
|
||
|
+ * so you can not umount /dev/mapper/foo
|
||
|
+ * - umount won't even recognize and translate /dev/dm-n to the mount
|
||
|
+ * point, apparently because of the '-' involved. Editing mtab and
|
||
|
+ * removing the '-' allows you to umount /dev/dmn successfully.
|
||
|
+ *
|
||
|
+ * This code restores the devmapper name after canonicalization,
|
||
|
+ * until a proper fix is implemented.
|
||
|
+ */
|
||
|
+
|
||
|
+char *ntfs_realpath_canonicalize(const char *path, char *canonical)
|
||
|
+{
|
||
|
+ char *p;
|
||
|
+
|
||
|
+ if (path == NULL)
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ if (!ntfs_realpath(path, canonical))
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ p = strrchr(canonical, '/');
|
||
|
+ if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) {
|
||
|
+ p = canonicalize_dm_name(p+1, canonical);
|
||
|
+ if (p)
|
||
|
+ return p;
|
||
|
+ }
|
||
|
+
|
||
|
+ return canonical;
|
||
|
+}
|
||
|
+
|
||
|
+#endif
|
||
|
diff --git a/libntfs-3g/volume.c b/libntfs-3g/volume.c
|
||
|
index 28e4c90..ca30585 100644
|
||
|
--- a/libntfs-3g/volume.c
|
||
|
+++ b/libntfs-3g/volume.c
|
||
|
@@ -67,6 +67,7 @@
|
||
|
#include "dir.h"
|
||
|
#include "logging.h"
|
||
|
#include "cache.h"
|
||
|
+#include "realpath.h"
|
||
|
#include "misc.h"
|
||
|
|
||
|
const char *ntfs_home =
|
||
|
@@ -1359,18 +1360,6 @@ int ntfs_umount(ntfs_volume *vol, const BOOL force __attribute__((unused)))
|
||
|
|
||
|
#ifdef HAVE_MNTENT_H
|
||
|
|
||
|
-#ifndef HAVE_REALPATH
|
||
|
-/**
|
||
|
- * realpath - If there is no realpath on the system
|
||
|
- */
|
||
|
-static char *realpath(const char *path, char *resolved_path)
|
||
|
-{
|
||
|
- strncpy(resolved_path, path, PATH_MAX);
|
||
|
- resolved_path[PATH_MAX] = '\0';
|
||
|
- return resolved_path;
|
||
|
-}
|
||
|
-#endif
|
||
|
-
|
||
|
/**
|
||
|
* ntfs_mntent_check - desc
|
||
|
*
|
||
|
@@ -1394,7 +1383,7 @@ static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
|
||
|
err = errno;
|
||
|
goto exit;
|
||
|
}
|
||
|
- if (!realpath(file, real_file)) {
|
||
|
+ if (!ntfs_realpath_canonicalize(file, real_file)) {
|
||
|
err = errno;
|
||
|
goto exit;
|
||
|
}
|
||
|
@@ -1403,7 +1392,7 @@ static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
|
||
|
goto exit;
|
||
|
}
|
||
|
while ((mnt = getmntent(f))) {
|
||
|
- if (!realpath(mnt->mnt_fsname, real_fsname))
|
||
|
+ if (!ntfs_realpath_canonicalize(mnt->mnt_fsname, real_fsname))
|
||
|
continue;
|
||
|
if (!strcmp(real_file, real_fsname))
|
||
|
break;
|
||
|
diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c
|
||
|
index aeadb17..9fa177f 100644
|
||
|
--- a/src/lowntfs-3g.c
|
||
|
+++ b/src/lowntfs-3g.c
|
||
|
@@ -3457,16 +3457,6 @@ static void usage(void)
|
||
|
EXEC_NAME, ntfs_home);
|
||
|
}
|
||
|
|
||
|
-#ifndef HAVE_REALPATH
|
||
|
-/* If there is no realpath() on the system, provide a dummy one. */
|
||
|
-static char *realpath(const char *path, char *resolved_path)
|
||
|
-{
|
||
|
- strncpy(resolved_path, path, PATH_MAX);
|
||
|
- resolved_path[PATH_MAX] = '\0';
|
||
|
- return resolved_path;
|
||
|
-}
|
||
|
-#endif
|
||
|
-
|
||
|
#if defined(linux) || defined(__uClinux__)
|
||
|
|
||
|
static const char *dev_fuse_msg =
|
||
|
@@ -3668,6 +3658,9 @@ static void setup_logging(char *parsed_options)
|
||
|
ctx->seccache = (struct PERMISSIONS_CACHE*)NULL;
|
||
|
|
||
|
ntfs_log_info("Version %s %s %d\n", VERSION, FUSE_TYPE, fuse_version());
|
||
|
+ if (strcmp(opts.arg_device,opts.device))
|
||
|
+ ntfs_log_info("Requested device %s canonicalized as %s\n",
|
||
|
+ opts.arg_device,opts.device);
|
||
|
ntfs_log_info("Mounted %s (%s, label \"%s\", NTFS %d.%d)\n",
|
||
|
opts.device, (ctx->ro) ? "Read-Only" : "Read-Write",
|
||
|
ctx->vol->vol_name, ctx->vol->major_ver,
|
||
|
diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c
|
||
|
index 80c084d..956f04d 100644
|
||
|
--- a/src/ntfs-3g.c
|
||
|
+++ b/src/ntfs-3g.c
|
||
|
@@ -3372,16 +3372,6 @@ static void usage(void)
|
||
|
EXEC_NAME, ntfs_home);
|
||
|
}
|
||
|
|
||
|
-#ifndef HAVE_REALPATH
|
||
|
-/* If there is no realpath() on the system, provide a dummy one. */
|
||
|
-static char *realpath(const char *path, char *resolved_path)
|
||
|
-{
|
||
|
- strncpy(resolved_path, path, PATH_MAX);
|
||
|
- resolved_path[PATH_MAX] = '\0';
|
||
|
- return resolved_path;
|
||
|
-}
|
||
|
-#endif
|
||
|
-
|
||
|
#if defined(linux) || defined(__uClinux__)
|
||
|
|
||
|
static const char *dev_fuse_msg =
|
||
|
@@ -3588,6 +3578,9 @@ static void setup_logging(char *parsed_options)
|
||
|
ctx->seccache = (struct PERMISSIONS_CACHE*)NULL;
|
||
|
|
||
|
ntfs_log_info("Version %s %s %d\n", VERSION, FUSE_TYPE, fuse_version());
|
||
|
+ if (strcmp(opts.arg_device,opts.device))
|
||
|
+ ntfs_log_info("Requested device %s canonicalized as %s\n",
|
||
|
+ opts.arg_device,opts.device);
|
||
|
ntfs_log_info("Mounted %s (%s, label \"%s\", NTFS %d.%d)\n",
|
||
|
opts.device, (ctx->ro) ? "Read-Only" : "Read-Write",
|
||
|
ctx->vol->vol_name, ctx->vol->major_ver,
|
||
|
diff --git a/src/ntfs-3g_common.c b/src/ntfs-3g_common.c
|
||
|
index 1ec24e0..b246b9c 100644
|
||
|
--- a/src/ntfs-3g_common.c
|
||
|
+++ b/src/ntfs-3g_common.c
|
||
|
@@ -47,6 +47,7 @@
|
||
|
#include "security.h"
|
||
|
#include "xattrs.h"
|
||
|
#include "ntfs-3g_common.h"
|
||
|
+#include "realpath.h"
|
||
|
#include "misc.h"
|
||
|
|
||
|
const char xattr_ntfs_3g[] = "ntfs-3g.";
|
||
|
@@ -509,7 +510,9 @@ int ntfs_parse_options(struct ntfs_options *popts, void (*usage)(void),
|
||
|
return -1;
|
||
|
|
||
|
/* Canonicalize device name (mtab, etc) */
|
||
|
- if (!realpath(optarg, popts->device)) {
|
||
|
+ popts->arg_device = optarg;
|
||
|
+ if (!ntfs_realpath_canonicalize(optarg,
|
||
|
+ popts->device)) {
|
||
|
ntfs_log_perror("%s: Failed to access "
|
||
|
"volume '%s'", EXEC_NAME, optarg);
|
||
|
free(popts->device);
|
||
|
diff --git a/src/ntfs-3g_common.h b/src/ntfs-3g_common.h
|
||
|
index 383dbe0..978569d 100644
|
||
|
--- a/src/ntfs-3g_common.h
|
||
|
+++ b/src/ntfs-3g_common.h
|
||
|
@@ -29,6 +29,7 @@ struct ntfs_options {
|
||
|
char *mnt_point; /* Mount point */
|
||
|
char *options; /* Mount options */
|
||
|
char *device; /* Device to mount */
|
||
|
+ char *arg_device; /* Device requested in argv */
|
||
|
} ;
|
||
|
|
||
|
typedef enum {
|
||
|
--
|
||
|
1.7.4.1
|
||
|
|