summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryn M. Reeves <bmr@redhat.com>2016-12-16 08:40:22 +0000
committerBryn M. Reeves <bmr@redhat.com>2016-12-16 13:44:42 +0000
commit50d124652c08b6505d10d32500f8440ce8da9608 (patch)
tree25171f89d6483d7f6ed36e8e31c2020975562034
parentfe0997d1ed1bad55959956ae3b7bc729b6d79244 (diff)
downloadlvm2-50d124652c08b6505d10d32500f8440ce8da9608.tar.gz
libdm: add dm_stats_start_filemapd()
Add a function to the stats API to launch the dmfilemapd filemap monitoring daemon. This carries out the first fork and execs dmfilemapd with the appropriate arguments.
-rw-r--r--libdm/.exported_symbols.DM_1_02_1381
-rw-r--r--libdm/libdevmapper.h12
-rw-r--r--libdm/libdm-stats.c96
3 files changed, 109 insertions, 0 deletions
diff --git a/libdm/.exported_symbols.DM_1_02_138 b/libdm/.exported_symbols.DM_1_02_138
index 1da129406..f639cc74a 100644
--- a/libdm/.exported_symbols.DM_1_02_138
+++ b/libdm/.exported_symbols.DM_1_02_138
@@ -2,3 +2,4 @@ dm_bit_get_last
dm_bit_get_prev
dm_stats_update_regions_from_fd
dm_bitset_parse_list
+dm_stats_start_filemapd
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index ae8f5fd11..1fbe2614a 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1358,6 +1358,18 @@ uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
uint64_t *dm_stats_update_regions_from_fd(struct dm_stats *dms, int fd,
uint64_t group_id);
+/*
+ * Start the dmfilemapd filemap monitoring daemon for the specified
+ * file descriptor, group, and file system path. The daemon will
+ * monitor the file for allocation changes, and when a change is
+ * detected, call dm_stats_update_regions_from_fd() to update the
+ * mapped regions for the file.
+ *
+ * The daemon can be stopped at any time by sending SIGTERM to the
+ * daemon pid.
+ */
+int dm_stats_start_filemapd(int fd, uint64_t group_id, const char *path,
+ unsigned foreground, unsigned verbose);
/*
* Call this to actually run the ioctl.
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
index 1eb516163..204c0e0a8 100644
--- a/libdm/libdm-stats.c
+++ b/libdm/libdm-stats.c
@@ -4812,6 +4812,95 @@ bad:
return NULL;
}
+#define NR_FILEMAPD_ARGS 5
+/*
+ * Start dmfilemapd to monitor the specified file descriptor, and to
+ * update the group given by 'group_id' when the file's allocation
+ * changes.
+ *
+ * usage: dmfilemapd <fd> <group_id> [<debug>[<log_level>]]
+ */
+int dm_stats_start_filemapd(int fd, uint64_t group_id, const char *path,
+ unsigned foreground, unsigned verbose)
+{
+ char *args[NR_FILEMAPD_ARGS + 1];
+ char fd_str[8], group_str[8], fg_str[2], verb_str[2];
+ int argc = 0;
+ pid_t pid;
+
+ if (fd < 0) {
+ log_error("dmfilemapd file descriptor must be "
+ "non-negative: %d", fd);
+ return 0;
+ }
+
+ if (foreground > 1) {
+ log_error("Invalid dmfilemapd foreground argument. "
+ "Must be 0 or 1: %d.", foreground);
+ return 0;
+ }
+
+ if (verbose > 3) {
+ log_error("Invalid dmfilemapd verbose argument. "
+ "Must be 0..3: %d.", verbose);
+ return 0;
+ }
+
+ /* set argv[0] */
+ args[argc++] = (char *) "dmfilemapd";
+
+ /* set <fd> */
+ if ((dm_snprintf(fd_str, sizeof(fd_str), "%d", fd)) < 0) {
+ log_error("Could not format fd argument.");
+ return 0;
+ }
+ args[argc++] = fd_str;
+
+ /* set <group_id> */
+ if ((dm_snprintf(group_str, sizeof(group_str), FMTu64, group_id)) < 0) {
+ log_error("Could not format group_id argument.");
+ return 0;
+ }
+ args[argc++] = group_str;
+
+ /* set <path> */
+ args[argc++] = (char *) path;
+
+ /* set <foreground> */
+ if ((dm_snprintf(fg_str, sizeof(fg_str), "%u", foreground)) < 0) {
+ log_error("Could not format foreground argument.");
+ return 0;
+ }
+ args[argc++] = fg_str;
+
+ /* set <verbose> */
+ if ((dm_snprintf(verb_str, sizeof(verb_str), "%u", verbose)) < 0) {
+ log_error("Could not format verbose argument.");
+ return 0;
+ }
+ args[argc++] = verb_str;
+
+ /* terminate args[argc] */
+ args[argc++] = NULL;
+
+ log_very_verbose("Spawning daemon as '%s %d " FMTu64 "%s %u %u'",
+ *args, fd, group_id, path, foreground, verbose);
+
+ if ((pid = fork()) < 0) {
+ log_error("Failed to fork filemapd process.");
+ return 0;
+ }
+
+ if (pid > 0) {
+ log_very_verbose("Forked filemapd process as pid %d", pid);
+ return 1;
+ }
+
+ execvp(args[0], args);
+ log_error("execv() failed.");
+ exit(127);
+}
+
#else /* HAVE_LINUX_FIEMAP */
uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
@@ -4829,6 +4918,13 @@ uint64_t *dm_stats_update_regions_from_fd(struct dm_stats *dms, int fd,
log_error("File mapping requires FIEMAP ioctl support.");
return 0;
}
+
+int dm_stats_start_filemapd(struct dm_stats *dms, int fd, uint64_t group_id,
+ const char *path)
+{
+ log_error("File mapping requires FIEMAP ioctl support.");
+ return 0;
+}
#endif /* HAVE_LINUX_FIEMAP */
/*