1 /* mountinfo.c - Track infos about mounts
2 * Copyright (C) 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <https://www.gnu.org/licenses/>.
31 #include "mountinfo.h"
38 /* The object to keep track of mount information. */
41 int in_use; /* The slot is in use. */
42 char *container; /* Name of the container. */
43 char *mountpoint; /* Name of the mounttype. */
44 int conttype; /* Type of the container. */
45 unsigned int rid; /* Identifier of the runner task. */
47 unsigned int remove:1; /* True if the mountpoint shall be removed
53 /* The allocated table of mounts and its size. */
54 static mtab_t mounttable;
55 size_t mounttable_size;
59 /* Add CONTAINER,MOUNTPOINT,CONTTYPE,RID to the mounttable. */
61 mountinfo_add_mount (const char *container, const char *mountpoint,
62 int conttype, unsigned int rid, int remove_flag)
67 for (idx=0; idx < mounttable_size; idx++)
68 if (!mounttable[idx].in_use)
70 if (!(idx < mounttable_size))
72 size_t nslots = mounttable_size;
74 mounttable_size += 10;
75 m = xtrycalloc (mounttable_size, sizeof *mounttable);
77 return gpg_error_from_syserror ();
80 for (idx=0; idx < nslots; idx++)
81 m[idx] = mounttable[idx];
85 m = mounttable + nslots;
91 m->container = xtrystrdup (container);
93 return gpg_error_from_syserror ();
94 m->mountpoint = xtrystrdup (mountpoint);
99 return gpg_error_from_syserror ();
101 m->conttype = conttype;
103 m->flags.remove = !!remove_flag;
110 /* Remove a mount info. Either the CONTAINER, the MOUNTPOINT or the
111 RID must be given. The first argument given is used. */
113 mountinfo_del_mount (const char *container, const char *mountpoint,
120 /* If a container or mountpint is givem search the RID via the
121 standard find function. */
122 if (container || mountpoint)
124 err = mountinfo_find_mount (container, mountpoint, &rid);
129 /* Find via RID and delete. */
130 for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++)
131 if (m->in_use && m->rid == rid)
133 if (m->flags.remove && m->mountpoint)
135 /* FIXME: This does not always work because the umount may
136 not have completed yet. We should add the mountpoints
137 to an idle queue and retry a remove. */
138 if (rmdir (m->mountpoint))
139 log_error ("error removing mount point '%s': %s\n",
141 gpg_strerror (gpg_error_from_syserror ()));
144 xfree (m->container);
146 xfree (m->mountpoint);
147 m->mountpoint = NULL;
150 return gpg_error (GPG_ERR_NOT_FOUND);
154 /* Find a mount and return its rid at R_RID. If CONTAINER is given,
155 the search is done by the container name, if it is not given the
156 search is done by MOUNTPOINT. */
158 mountinfo_find_mount (const char *container, const char *mountpoint,
166 for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++)
167 if (m->in_use && !strcmp (m->container, container))
172 for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++)
173 if (m->in_use && !strcmp (m->mountpoint, mountpoint))
177 idx = mounttable_size;
178 if (!(idx < mounttable_size))
179 return gpg_error (GPG_ERR_NOT_FOUND);
186 /* Dump all info to the log stream. */
188 mountinfo_dump_all (void)
193 for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++)
195 log_info ("mtab[%d] %s on %s type %d rid %u%s\n",
196 (int)idx, m->container, m->mountpoint, m->conttype, m->rid,
197 m->flags.remove?" [remove]":"");