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 <http://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 fucntion. */
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 idx
, m
->container
, m
->mountpoint
, m
->conttype
, m
->rid
,
197 m
->flags
.remove
?" [remove]":"");