diff options
author | Bryn M. Reeves <bmr@redhat.com> | 2016-12-16 08:40:22 +0000 |
---|---|---|
committer | Bryn M. Reeves <bmr@redhat.com> | 2016-12-16 13:44:42 +0000 |
commit | 50d124652c08b6505d10d32500f8440ce8da9608 (patch) | |
tree | 25171f89d6483d7f6ed36e8e31c2020975562034 | |
parent | fe0997d1ed1bad55959956ae3b7bc729b6d79244 (diff) | |
download | lvm2-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_138 | 1 | ||||
-rw-r--r-- | libdm/libdevmapper.h | 12 | ||||
-rw-r--r-- | libdm/libdm-stats.c | 96 |
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 */ /* |