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.
367 lines
9.5 KiB
367 lines
9.5 KiB
7 years ago
|
autofs-5.0.7 - teach dumpmaps to output simple key value pairs
|
||
|
|
||
|
From: Ian Kent <raven@themaw.net>
|
||
|
|
||
|
The dumpmaps option doesn't allow maps to be output in <key, value>
|
||
|
pairs suitable for use as a file map.
|
||
|
|
||
|
This could be useful to save current maps as a backup for emergency
|
||
|
use.
|
||
|
|
||
|
If the dumpmaps option is given and is followed by two parameters,
|
||
|
"<map type> <map name>" then simple <key, value> pairs that would
|
||
|
be read in by a map read are printed to stdout if the given map type
|
||
|
and map name are found in the map configuration.
|
||
|
|
||
|
If the map is an LDAP map and there is more than one map of same name
|
||
|
in different base dns only the first map encountered by autofs will
|
||
|
be listed.
|
||
|
|
||
|
If the map type is an old style multi-map and any one of the map
|
||
|
names in the multi-map entry matches the given map name the entries
|
||
|
that would be used by autofs for the whole multi-map will be listed.
|
||
|
---
|
||
|
CHANGELOG | 1
|
||
|
daemon/automount.c | 56 ++++++++++++---
|
||
|
include/master.h | 1
|
||
|
lib/master.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
man/automount.8 | 20 +++++
|
||
|
5 files changed, 250 insertions(+), 15 deletions(-)
|
||
|
|
||
|
--- autofs-5.0.7.orig/CHANGELOG
|
||
|
+++ autofs-5.0.7/CHANGELOG
|
||
|
@@ -60,6 +60,7 @@
|
||
|
- fix fix wildcard multi map regression.
|
||
|
- fix dumpmaps multi output.
|
||
|
- try and cleanup after dumpmaps.
|
||
|
+- teach dumpmaps to output simple key value pairs.
|
||
|
|
||
|
25/07/2012 autofs-5.0.7
|
||
|
=======================
|
||
|
--- autofs-5.0.7.orig/daemon/automount.c
|
||
|
+++ autofs-5.0.7/daemon/automount.c
|
||
|
@@ -1725,7 +1725,8 @@ static void usage(void)
|
||
|
" -f --foreground do not fork into background\n"
|
||
|
" -r --random-multimount-selection\n"
|
||
|
" use ramdom replicated server selection\n"
|
||
|
- " -m --dumpmaps dump automounter maps and exit\n"
|
||
|
+ " -m --dumpmaps [<map type> <map name>]\n"
|
||
|
+ " dump automounter maps and exit\n"
|
||
|
" -n --negative-timeout n\n"
|
||
|
" set the timeout for failed key lookups.\n"
|
||
|
" -O --global-options\n"
|
||
|
@@ -2125,22 +2126,33 @@ int main(int argc, char *argv[])
|
||
|
program);
|
||
|
#endif
|
||
|
|
||
|
- if (argc == 0)
|
||
|
- master_list = master_new(NULL, timeout, ghost);
|
||
|
- else
|
||
|
- master_list = master_new(argv[0], timeout, ghost);
|
||
|
-
|
||
|
- if (!master_list) {
|
||
|
- printf("%s: can't create master map %s", program, argv[0]);
|
||
|
- exit(1);
|
||
|
- }
|
||
|
-
|
||
|
if (dumpmaps) {
|
||
|
struct master_mapent *entry;
|
||
|
struct list_head *head, *p;
|
||
|
struct mapent_cache *nc;
|
||
|
+ const char *type = NULL;
|
||
|
+ const char *name = NULL;
|
||
|
+ const char *master = NULL;
|
||
|
+
|
||
|
+ if (argc > 0) {
|
||
|
+ if (argc >= 2) {
|
||
|
+ type = argv[0];
|
||
|
+ name = argv[1];
|
||
|
+ }
|
||
|
+ if (argc == 3)
|
||
|
+ master = argv[2];
|
||
|
+ }
|
||
|
|
||
|
- open_log();
|
||
|
+ if (master)
|
||
|
+ master_list = master_new(NULL, timeout, ghost);
|
||
|
+ else
|
||
|
+ master_list = master_new(master, timeout, ghost);
|
||
|
+ if (!master_list) {
|
||
|
+ printf("%s: can't create master map", program);
|
||
|
+ exit(1);
|
||
|
+ }
|
||
|
+
|
||
|
+ log_to_stderr();
|
||
|
|
||
|
master_init_scan();
|
||
|
|
||
|
@@ -2153,7 +2165,15 @@ int main(int argc, char *argv[])
|
||
|
master_list->nc = nc;
|
||
|
|
||
|
lookup_nss_read_master(master_list, 0);
|
||
|
- master_show_mounts(master_list);
|
||
|
+ if (type) {
|
||
|
+ const char *map = basename(name);
|
||
|
+ if (!map)
|
||
|
+ printf("%s: invalid map name %s\n",
|
||
|
+ program, name);
|
||
|
+ else
|
||
|
+ dump_map(master_list, type, map);
|
||
|
+ } else
|
||
|
+ master_show_mounts(master_list);
|
||
|
|
||
|
head = &master_list->mounts;
|
||
|
p = head->next;
|
||
|
@@ -2168,6 +2188,16 @@ int main(int argc, char *argv[])
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
+ if (argc == 0)
|
||
|
+ master_list = master_new(NULL, timeout, ghost);
|
||
|
+ else
|
||
|
+ master_list = master_new(argv[0], timeout, ghost);
|
||
|
+
|
||
|
+ if (!master_list) {
|
||
|
+ printf("%s: can't create master map %s", program, argv[0]);
|
||
|
+ exit(1);
|
||
|
+ }
|
||
|
+
|
||
|
become_daemon(foreground, daemon_check);
|
||
|
|
||
|
if (pthread_attr_init(&th_attr)) {
|
||
|
--- autofs-5.0.7.orig/include/master.h
|
||
|
+++ autofs-5.0.7/include/master.h
|
||
|
@@ -112,6 +112,7 @@ int master_submount_list_empty(struct au
|
||
|
int master_notify_submount(struct autofs_point *, const char *path, enum states);
|
||
|
void master_notify_state_change(struct master *, int);
|
||
|
int master_mount_mounts(struct master *, time_t, int);
|
||
|
+int dump_map(struct master *, const char *, const char *);
|
||
|
int master_show_mounts(struct master *);
|
||
|
extern inline unsigned int master_get_logopt(void);
|
||
|
int master_list_empty(struct master *);
|
||
|
--- autofs-5.0.7.orig/lib/master.c
|
||
|
+++ autofs-5.0.7/lib/master.c
|
||
|
@@ -1329,6 +1329,193 @@ static void print_map_info(struct map_so
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+static int match_type(const char *source, const char *type)
|
||
|
+{
|
||
|
+ if (!strcmp(source, type))
|
||
|
+ return 1;
|
||
|
+ /* Sources file and files are synonymous */
|
||
|
+ if (!strncmp(source, type, 4) && (strlen(source) <= 5))
|
||
|
+ return 1;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static char *get_map_name(const char *string)
|
||
|
+{
|
||
|
+ char *name, *tmp;
|
||
|
+ char *start, *end, *base;
|
||
|
+
|
||
|
+ tmp = strdup(string);
|
||
|
+ if (!tmp) {
|
||
|
+ printf("error: allocation failure: %s\n", strerror(errno));
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ base = basename(tmp);
|
||
|
+ end = strchr(base, ',');
|
||
|
+ if (end)
|
||
|
+ *end = '\0';
|
||
|
+ start = strchr(tmp, '=');
|
||
|
+ if (start)
|
||
|
+ start++;
|
||
|
+ else {
|
||
|
+ char *colon = strrchr(base, ':');
|
||
|
+ if (colon)
|
||
|
+ start = ++colon;
|
||
|
+ else
|
||
|
+ start = base;
|
||
|
+ }
|
||
|
+
|
||
|
+ name = strdup(start);
|
||
|
+ if (!name)
|
||
|
+ printf("error: allocation failure: %s\n", strerror(errno));
|
||
|
+ free(tmp);
|
||
|
+
|
||
|
+ return name;
|
||
|
+}
|
||
|
+
|
||
|
+static int match_name(struct map_source *source, const char *name)
|
||
|
+{
|
||
|
+ int argc = source->argc;
|
||
|
+ int ret = 0;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * This can't work for old style "multi" type sources since
|
||
|
+ * there's no way to know from which map the cache entry came
|
||
|
+ * from and duplicate entries are ignored at map read time.
|
||
|
+ * All we can really do is list all the entries for the given
|
||
|
+ * multi map if one of its map names matches.
|
||
|
+ */
|
||
|
+ for (i = 0; i < argc; i++) {
|
||
|
+ if (i == 0 || !strcmp(source->argv[i], "--")) {
|
||
|
+ if (i != 0) {
|
||
|
+ i++;
|
||
|
+ if (i >= argc)
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (source->argv[i] && *source->argv[i] != '-') {
|
||
|
+ char *map = get_map_name(source->argv[i]);
|
||
|
+ if (!map)
|
||
|
+ break;
|
||
|
+ if (!strcmp(map, name)) {
|
||
|
+ ret = 1;
|
||
|
+ free(map);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ free(map);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+int dump_map(struct master *master, const char *type, const char *name)
|
||
|
+{
|
||
|
+ struct list_head *p, *head;
|
||
|
+
|
||
|
+ if (list_empty(&master->mounts)) {
|
||
|
+ printf("no master map entries found\n");
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ head = &master->mounts;
|
||
|
+ p = head->next;
|
||
|
+ while (p != head) {
|
||
|
+ struct map_source *source;
|
||
|
+ struct master_mapent *this;
|
||
|
+ struct autofs_point *ap;
|
||
|
+ time_t now = time(NULL);
|
||
|
+
|
||
|
+ this = list_entry(p, struct master_mapent, list);
|
||
|
+ p = p->next;
|
||
|
+
|
||
|
+ ap = this->ap;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * Ensure we actually read indirect map entries so we can
|
||
|
+ * list them. The map reads won't read any indirect map
|
||
|
+ * entries (other than those in a file map) unless the
|
||
|
+ * browse option is set.
|
||
|
+ */
|
||
|
+ if (ap->type == LKP_INDIRECT)
|
||
|
+ ap->flags |= MOUNT_FLAG_GHOST;
|
||
|
+
|
||
|
+ /* Read the map content into the cache */
|
||
|
+ if (lookup_nss_read_map(ap, NULL, now))
|
||
|
+ lookup_prune_cache(ap, now);
|
||
|
+ else {
|
||
|
+ printf("failed to read map\n");
|
||
|
+ lookup_close_lookup(ap);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!this->maps) {
|
||
|
+ printf("no map sources found for %s\n", ap->path);
|
||
|
+ lookup_close_lookup(ap);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
+ source = this->maps;
|
||
|
+ while (source) {
|
||
|
+ struct map_source *instance;
|
||
|
+ struct mapent *me;
|
||
|
+
|
||
|
+ instance = NULL;
|
||
|
+ if (source->type) {
|
||
|
+ if (!match_type(source->type, type)) {
|
||
|
+ source = source->next;
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ if (!match_name(source, name)) {
|
||
|
+ source = source->next;
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ instance = source;
|
||
|
+ } else {
|
||
|
+ struct map_source *map;
|
||
|
+
|
||
|
+ map = source->instance;
|
||
|
+ while (map) {
|
||
|
+ if (!match_type(map->type, type)) {
|
||
|
+ map = map->next;
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ if (!match_name(map, name)) {
|
||
|
+ map = map->next;
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ instance = map;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!instance) {
|
||
|
+ source = source->next;
|
||
|
+ lookup_close_lookup(ap);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
+ me = cache_lookup_first(source->mc);
|
||
|
+ if (!me)
|
||
|
+ printf("no keys found in map\n");
|
||
|
+ else {
|
||
|
+ do {
|
||
|
+ if (me->source == instance)
|
||
|
+ printf("%s\t%s\n", me->key, me->mapent);
|
||
|
+ } while ((me = cache_lookup_next(source->mc, me)));
|
||
|
+ }
|
||
|
+
|
||
|
+ lookup_close_lookup(ap);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ lookup_close_lookup(ap);
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
int master_show_mounts(struct master *master)
|
||
|
{
|
||
|
struct list_head *p, *head;
|
||
|
--- autofs-5.0.7.orig/man/automount.8
|
||
|
+++ autofs-5.0.7/man/automount.8
|
||
|
@@ -57,8 +57,24 @@ Run the daemon in the foreground and log
|
||
|
Enables the use of ramdom selection when choosing a host from a
|
||
|
list of replicated servers.
|
||
|
.TP
|
||
|
-.I "\-m, \-\-dumpmaps"
|
||
|
-Dump configured automounter maps, then exit.
|
||
|
+.I "\-m, \-\-dumpmaps [<map type> <map name>]"
|
||
|
+With no parameters, list information about the configured automounter
|
||
|
+maps, then exit.
|
||
|
+
|
||
|
+If the dumpmaps option is given and is followed by two parameters,
|
||
|
+"<map type> <map name>" then simple "<key, value>" pairs that would
|
||
|
+be read in by a map read are printed to stdout if the given map type
|
||
|
+and map name are found in the map configuration.
|
||
|
+
|
||
|
+If the map is an LDAP map and there is more than one map of same name
|
||
|
+in different base dns only the first map encountered by autofs will
|
||
|
+be listed. Similarly, if the map is a file map and there is more than
|
||
|
+one map of the same name in different directories, only the first map
|
||
|
+encountered will be listed.
|
||
|
+
|
||
|
+If the map type is an old style multi-map and any one of the map
|
||
|
+names in the multi-map entry matches the given map name the entries
|
||
|
+that would be used by autofs for the whole multi-map will be listed.
|
||
|
.TP
|
||
|
.I "\-O, \-\-global-options"
|
||
|
Allows the specification of global mount options used for all master
|