summaryrefslogtreecommitdiff
path: root/legacy/eeze
diff options
context:
space:
mode:
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>2012-07-23 14:08:13 +0000
committerMike Blumenkrantz <michael.blumenkrantz@gmail.com>2012-07-23 14:08:13 +0000
commit7914a063eafa807e0276ac38e88913e5660432a7 (patch)
treed82226e623d63476acfaa05c93da207d23fb1829 /legacy/eeze
parenta32308d4e8d8b2c5c3c0de65f0ef213a34f2f886 (diff)
add a third libmount backend for "current" libmount, where we are too cool for /etc/mtab
SVN revision: 74326
Diffstat (limited to 'legacy/eeze')
-rw-r--r--legacy/eeze/ChangeLog5
-rw-r--r--legacy/eeze/NEWS5
-rw-r--r--legacy/eeze/configure.ac7
-rw-r--r--legacy/eeze/src/lib/Makefile.am4
-rw-r--r--legacy/eeze/src/lib/eeze_disk_libmount_new.c515
-rw-r--r--legacy/eeze/src/lib/eeze_disk_mount.c1
6 files changed, 532 insertions, 5 deletions
diff --git a/legacy/eeze/ChangeLog b/legacy/eeze/ChangeLog
index 6166e07746..029dbef1e4 100644
--- a/legacy/eeze/ChangeLog
+++ b/legacy/eeze/ChangeLog
@@ -105,3 +105,8 @@
105 105
106 * Add a check in event monitoring for disks which ensures that 106 * Add a check in event monitoring for disks which ensures that
107 device changes for loopback devices are picked up 107 device changes for loopback devices are picked up
108
1092012-07-23 Mike Blumenkrantz
110
111 * Add yet another libmount backend for eeze_disk to handle current
112 setups which do not have mtab and instead use /proc/self/mountinfo
diff --git a/legacy/eeze/NEWS b/legacy/eeze/NEWS
index 23d7195335..b953461a7c 100644
--- a/legacy/eeze/NEWS
+++ b/legacy/eeze/NEWS
@@ -1,11 +1,12 @@
1Eeze 1.3.0 1Eeze 1.7.0
2 2
3Changes since Eeze 1.1.0: 3Changes since Eeze 1.2.0:
4------------------------- 4-------------------------
5 5
6Additions: 6Additions:
7 7
8 * Joystick support 8 * Joystick support
9 * Support for mtab-less systems
9 10
10Changes since Eeze 1.1.0: 11Changes since Eeze 1.1.0:
11------------------------- 12-------------------------
diff --git a/legacy/eeze/configure.ac b/legacy/eeze/configure.ac
index 1056f36d95..ae3fe69887 100644
--- a/legacy/eeze/configure.ac
+++ b/legacy/eeze/configure.ac
@@ -147,12 +147,13 @@ if test "x$eeze_mount" = "xyes";then
147fi 147fi
148if test -n "$mount_v";then 148if test -n "$mount_v";then
149 AM_CONDITIONAL([OLD_LIBMOUNT], [test "$(echo $mount_v | cut -d'.' -f2)" -lt 19]) 149 AM_CONDITIONAL([OLD_LIBMOUNT], [test "$(echo $mount_v | cut -d'.' -f2)" -lt 19])
150 AM_CONDITIONAL([NEW_LIBMOUNT], [test "$(echo $mount_v | cut -d'.' -f2)" -gt 19])
150else 151else
151 AM_CONDITIONAL([OLD_LIBMOUNT], [false]) 152 AM_CONDITIONAL([OLD_LIBMOUNT], [false])
152fi 153fi
153if test -z "$OLD_LIBMOUNT_TRUE" ; then 154AM_COND_IF([OLD_LIBMOUNT], [
154 AC_DEFINE_UNQUOTED([OLD_LIBMOUNT], [1], [using first version of libmount]) 155 AC_DEFINE_UNQUOTED([OLD_LIBMOUNT], [1], [using first version of libmount])
155fi 156 ],[])
156 157
157AC_CHECK_HEADERS([netinet/in.h]) 158AC_CHECK_HEADERS([netinet/in.h])
158want_ipv6="yes" 159want_ipv6="yes"
diff --git a/legacy/eeze/src/lib/Makefile.am b/legacy/eeze/src/lib/Makefile.am
index eb3a18fac3..b14e44d401 100644
--- a/legacy/eeze/src/lib/Makefile.am
+++ b/legacy/eeze/src/lib/Makefile.am
@@ -21,8 +21,12 @@ if HAVE_EEZE_MOUNT
21if OLD_LIBMOUNT 21if OLD_LIBMOUNT
22 libeeze_la_SOURCES += eeze_disk_libmount_old.c 22 libeeze_la_SOURCES += eeze_disk_libmount_old.c
23else 23else
24if NEW_LIBMOUNT
25 libeeze_la_SOURCES += eeze_disk_libmount_new.c
26else
24 libeeze_la_SOURCES += eeze_disk_libmount.c 27 libeeze_la_SOURCES += eeze_disk_libmount.c
25endif 28endif
29endif
26 includes_HEADERS += Eeze_Disk.h 30 includes_HEADERS += Eeze_Disk.h
27else 31else
28 AM_CFLAGS = @EEZE_CFLAGS@ 32 AM_CFLAGS = @EEZE_CFLAGS@
diff --git a/legacy/eeze/src/lib/eeze_disk_libmount_new.c b/legacy/eeze/src/lib/eeze_disk_libmount_new.c
new file mode 100644
index 0000000000..f9c7e229eb
--- /dev/null
+++ b/legacy/eeze/src/lib/eeze_disk_libmount_new.c
@@ -0,0 +1,515 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#ifndef USE_UNSTABLE_LIBMOUNT_API
6# define USE_UNSTABLE_LIBMOUNT_API 1
7#endif
8
9#include <Ecore.h>
10#include <Eeze.h>
11#include <Eeze_Disk.h>
12#include <libmount.h>
13#include <unistd.h>
14
15#include "eeze_udev_private.h"
16#include "eeze_disk_private.h"
17
18/*
19 *
20 * PRIVATE
21 *
22 */
23
24static struct libmnt_optmap eeze_optmap[] =
25{
26 { "loop[=]", EEZE_DISK_MOUNTOPT_LOOP, 0 },
27 { "utf8", EEZE_DISK_MOUNTOPT_UTF8, 0 },
28 { "noexec", EEZE_DISK_MOUNTOPT_NOEXEC, 0 },
29 { "nosuid", EEZE_DISK_MOUNTOPT_NOSUID, 0 },
30 { "remount", EEZE_DISK_MOUNTOPT_REMOUNT, 0 },
31 { "uid[=]", EEZE_DISK_MOUNTOPT_UID, 0 },
32 { NULL, 0, 0 }
33};
34typedef struct libmnt_table libmnt_table;
35typedef struct libmnt_fs libmnt_fs;
36typedef struct libmnt_cache libmnt_cache;
37static Ecore_File_Monitor *_fstab_mon = NULL;
38static Eina_Bool _watching = EINA_FALSE;
39static Eina_Bool _fstab_scan_active = EINA_FALSE;
40static libmnt_cache *_eeze_mount_mtab_cache = NULL;
41static libmnt_cache *_eeze_mount_fstab_cache = NULL;
42static libmnt_table *_eeze_mount_mtab = NULL;
43static libmnt_table *_eeze_mount_fstab = NULL;
44extern Eina_List *_eeze_disks;
45
46static Ecore_Fd_Handler *_mountinfo_fdh = NULL;
47static FILE *_mountinfo = NULL;
48
49static libmnt_table *_eeze_mount_tab_parse(const char *filename);
50static void _eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon __UNUSED__, Ecore_File_Event event __UNUSED__, const char *path);
51
52static int
53_eeze_mount_tab_parse_errcb(libmnt_table *tab __UNUSED__, const char *filename, int line)
54{
55 ERR("%s:%d: could not parse line!", filename, line); /* most worthless error reporting ever. */
56 return -1;
57}
58
59/*
60 * I could use mnt_new_table_from_file() but this way gives much more detailed output
61 * on failure so why not
62 */
63static libmnt_table *
64_eeze_mount_tab_parse(const char *filename)
65{
66 libmnt_table *tab;
67
68 if (!(tab = mnt_new_table())) return NULL;
69 if (mnt_table_set_parser_errcb(tab, _eeze_mount_tab_parse_errcb))
70 {
71 ERR("Alloc!");
72 mnt_free_table(tab);
73 return NULL;
74 }
75
76 if (!mnt_table_parse_file(tab, filename))
77 return tab;
78
79 mnt_free_table(tab);
80 return NULL;
81}
82
83static void
84_eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon __UNUSED__, Ecore_File_Event event __UNUSED__, const char *path)
85{
86 libmnt_table *bak;
87
88 if (_fstab_scan_active)
89 /* prevent scans from triggering a scan */
90 return;
91
92 bak = _eeze_mount_mtab;
93 _eeze_mount_mtab = _eeze_mount_tab_parse(path);
94 if (!_eeze_mount_mtab)
95 {
96 ERR("Could not parse %s! keeping old tab...", path);
97 goto error;
98 }
99
100 mnt_free_table(bak);
101 if (data)
102 {
103 mnt_free_cache(_eeze_mount_mtab_cache);
104 _eeze_mount_mtab_cache = mnt_new_cache();
105 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
106 }
107 else
108 {
109 mnt_free_cache(_eeze_mount_fstab_cache);
110 _eeze_mount_fstab_cache = mnt_new_cache();
111 mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
112 }
113 return;
114
115error:
116 mnt_free_table(_eeze_mount_mtab);
117 _eeze_mount_mtab = bak;
118}
119
120/* on tab change, check differences
121 * based on code from findmnt
122 */
123static Eina_Bool
124_eeze_mount_fdh(void *d __UNUSED__, Ecore_Fd_Handler *fdh __UNUSED__)
125{
126 libmnt_table *tb_new;
127 libmnt_fs *old, *new;
128 int change;
129 struct libmnt_iter *itr = NULL;
130 struct libmnt_tabdiff *diff = NULL;
131
132 tb_new = mnt_new_table();
133 EINA_SAFETY_ON_NULL_RETURN_VAL(tb_new, ECORE_CALLBACK_RENEW);
134 EINA_SAFETY_ON_TRUE_GOTO(mnt_table_set_parser_errcb(tb_new, _eeze_mount_tab_parse_errcb), err);
135 itr = mnt_new_iter(MNT_ITER_BACKWARD);
136 EINA_SAFETY_ON_NULL_GOTO(itr, err);
137 diff = mnt_new_tabdiff();
138 EINA_SAFETY_ON_NULL_GOTO(diff, err);
139 rewind(_mountinfo);
140 if (mnt_table_parse_stream(tb_new, _mountinfo, "/proc/self/mountinfo"))
141 {
142 ERR("PARSING FAILED FOR /proc/self/mountinfo! THIS IS WEIRD!");
143 goto err;
144 }
145 change = mnt_diff_tables(diff, _eeze_mount_mtab, tb_new);
146 if (change < 0)
147 {
148 ERR("DIFFING FAILED FOR /proc/self/mountinfo! THIS IS ALSO WEIRD!");
149 goto err;
150 }
151 if (!change) goto err;
152 while (!mnt_tabdiff_next_change(diff, itr, &old, &new, &change))
153 {
154 const char *src;
155 Eeze_Disk *disk;
156 Eina_Bool found = EINA_FALSE;
157 Eeze_Event_Disk_Mount *e;
158 Eina_List *l;
159
160 src = mnt_fs_get_source(new);
161 if (!src) continue;
162 EINA_LIST_FOREACH(_eeze_disks, l, disk)
163 {
164 if (!strcmp(src, eeze_disk_devpath_get(disk)))
165 {
166 found = EINA_TRUE;
167 break;
168 }
169 }
170 if (!found) continue;
171 switch (change)
172 {
173 case MNT_TABDIFF_MOUNT:
174 disk->mounted = EINA_TRUE;
175 eina_stringshare_replace(&disk->mount_point, mnt_fs_get_target(new));
176 e = malloc(sizeof(Eeze_Event_Disk_Mount));
177 if (e)
178 {
179 e->disk = disk;
180 ecore_event_add(EEZE_EVENT_DISK_MOUNT, e, NULL, NULL);
181 }
182 break;
183 case MNT_TABDIFF_UMOUNT:
184 if (!mnt_fs_get_target(new))
185 disk->mounted = EINA_FALSE;
186 eina_stringshare_replace(&disk->mount_point, NULL);
187 e = malloc(sizeof(Eeze_Event_Disk_Mount));
188 if (e)
189 {
190 e->disk = disk;
191 ecore_event_add(EEZE_EVENT_DISK_UNMOUNT, e, NULL, NULL);
192 }
193 break;
194 /* anything could have happened here, send both events to flush */
195 case MNT_TABDIFF_REMOUNT:
196 case MNT_TABDIFF_MOVE:
197 if (!mnt_fs_get_target(new))
198 disk->mounted = EINA_FALSE;
199 eina_stringshare_replace(&disk->mount_point, mnt_fs_get_target(new));
200 e = malloc(sizeof(Eeze_Event_Disk_Mount));
201 if (e)
202 {
203 e->disk = disk;
204 ecore_event_add(EEZE_EVENT_DISK_UNMOUNT, e, NULL, NULL);
205 }
206 e = malloc(sizeof(Eeze_Event_Disk_Mount));
207 if (e)
208 {
209 e->disk = disk;
210 ecore_event_add(EEZE_EVENT_DISK_MOUNT, e, NULL, NULL);
211 }
212 default:
213 break;
214 }
215 }
216
217 mnt_free_cache(_eeze_mount_mtab_cache);
218 _eeze_mount_mtab_cache = mnt_new_cache();
219 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
220 mnt_free_table(_eeze_mount_mtab);
221 _eeze_mount_mtab = tb_new;
222 return ECORE_CALLBACK_RENEW;
223err:
224 if (tb_new) mnt_free_table(tb_new);
225 if (itr) mnt_free_iter(itr);
226 if (diff) mnt_free_tabdiff(diff);
227 return ECORE_CALLBACK_RENEW;
228}
229
230/*
231 *
232 * INVISIBLE
233 *
234 */
235
236Eina_Bool
237eeze_libmount_init(void)
238{
239 /* placeholder */
240 return EINA_TRUE;
241}
242
243void
244eeze_libmount_shutdown(void)
245{
246 if (_eeze_mount_fstab)
247 {
248 mnt_free_table(_eeze_mount_fstab);
249 mnt_free_cache(_eeze_mount_fstab_cache);
250 }
251 if (_eeze_mount_mtab)
252 {
253 mnt_free_table(_eeze_mount_mtab);
254 mnt_free_cache(_eeze_mount_mtab_cache);
255 }
256 eeze_mount_tabs_unwatch();
257}
258
259unsigned long
260eeze_disk_libmount_opts_get(Eeze_Disk *disk)
261{
262 libmnt_fs *mnt;
263 const char *opts;
264 unsigned long f = 0;
265
266 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
267 return 0;
268
269 mnt = mnt_table_find_tag(_eeze_mount_mtab, "UUID", eeze_disk_uuid_get(disk), MNT_ITER_BACKWARD);
270 if (!mnt)
271 mnt = mnt_table_find_tag(_eeze_mount_fstab, "UUID", eeze_disk_uuid_get(disk), MNT_ITER_BACKWARD);
272
273 if (!mnt) return 0;
274
275 opts = mnt_fs_get_fs_options(mnt);
276 if (!opts) return 0;
277 if (!mnt_optstr_get_flags(opts, &f, eeze_optmap)) return 0;
278 return f;
279}
280
281/*
282 * helper function to return whether a disk is mounted
283 */
284Eina_Bool
285eeze_disk_libmount_mounted_get(Eeze_Disk *disk)
286{
287 libmnt_fs *mnt;
288
289 if (!disk)
290 return EINA_FALSE;
291
292 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
293 return EINA_FALSE;
294
295 mnt = mnt_table_find_source(_eeze_mount_mtab, eeze_disk_devpath_get(disk), MNT_ITER_BACKWARD);
296 if (!mnt)
297 {
298 disk->mounted = EINA_FALSE;
299 return EINA_FALSE;
300 }
301
302 eina_stringshare_replace(&disk->mount_point, mnt_fs_get_target(mnt));
303 disk->mounted = EINA_TRUE;
304 return EINA_TRUE;
305}
306
307
308/*
309 * helper function to return the device that is mounted at a mount point
310 */
311const char *
312eeze_disk_libmount_mp_find_source(const char *mount_point)
313{
314 libmnt_fs *mnt;
315
316 if (!mount_point)
317 return NULL;
318
319 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
320 return NULL;
321
322 mnt = mnt_table_find_target(_eeze_mount_mtab, mount_point, MNT_ITER_BACKWARD);
323 if (!mnt)
324 mnt = mnt_table_find_target(_eeze_mount_fstab, mount_point, MNT_ITER_BACKWARD);
325
326 if (!mnt)
327 return NULL;
328
329 return mnt_fs_get_source(mnt);
330}
331
332/*
333 * helper function to return a mount point from a uuid
334 */
335const char *
336eeze_disk_libmount_mp_lookup_by_uuid(const char *uuid)
337{
338 libmnt_fs *mnt;
339
340 if (!uuid)
341 return NULL;
342
343 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
344 return NULL;
345
346 mnt = mnt_table_find_tag(_eeze_mount_fstab, "UUID", uuid, MNT_ITER_BACKWARD);
347
348 if (!mnt)
349 return NULL;
350
351 return mnt_fs_get_target(mnt);
352}
353
354/*
355 * helper function to return a mount point from a label
356 */
357const char *
358eeze_disk_libmount_mp_lookup_by_label(const char *label)
359{
360 libmnt_fs *mnt;
361
362 if (!label)
363 return NULL;
364
365 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
366 return NULL;
367
368 mnt = mnt_table_find_tag(_eeze_mount_fstab, "LABEL", label, MNT_ITER_BACKWARD);
369
370 if (!mnt)
371 return NULL;
372
373 return mnt_fs_get_target(mnt);
374}
375
376/*
377 * helper function to return a mount point from a /dev/ path
378 */
379const char *
380eeze_disk_libmount_mp_lookup_by_devpath(const char *devpath)
381{
382 libmnt_fs *mnt;
383
384 if (!devpath)
385 return NULL;
386
387 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
388 return NULL;
389
390 mnt = mnt_table_find_srcpath(_eeze_mount_mtab, devpath, MNT_ITER_BACKWARD);
391 if (!mnt)
392 mnt = mnt_table_find_srcpath(_eeze_mount_fstab, devpath, MNT_ITER_BACKWARD);
393
394 if (!mnt)
395 return NULL;
396
397 return mnt_fs_get_target(mnt);
398}
399
400/*
401 *
402 * API
403 *
404 */
405
406EAPI Eina_Bool
407eeze_mount_tabs_watch(void)
408{
409 libmnt_table *bak;
410
411 if (_watching)
412 return EINA_TRUE;
413
414 bak = _eeze_mount_tab_parse("/proc/self/mountinfo");
415 EINA_SAFETY_ON_NULL_GOTO(bak, error);
416
417 mnt_free_table(_eeze_mount_mtab);
418 _eeze_mount_mtab = bak;
419 bak = _eeze_mount_tab_parse("/etc/fstab");
420 EINA_SAFETY_ON_NULL_GOTO(bak, error);
421
422 mnt_free_table(_eeze_mount_fstab);
423 _eeze_mount_fstab = bak;
424
425 _eeze_mount_mtab_cache = mnt_new_cache();
426 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
427
428 _eeze_mount_fstab_cache = mnt_new_cache();
429 mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
430
431 _mountinfo = fopen("/proc/self/mountinfo", "r");
432 if (!_mountinfo) goto error;
433 _mountinfo_fdh = ecore_main_fd_handler_add(fileno(_mountinfo), ECORE_FD_ERROR, _eeze_mount_fdh, NULL, NULL, NULL);
434 if (!_mountinfo_fdh) goto error;
435 _fstab_mon = ecore_file_monitor_add("/etc/fstab", _eeze_mount_tab_watcher, NULL);
436 _watching = EINA_TRUE;
437
438 return EINA_TRUE;
439
440error:
441 if (_mountinfo) fclose(_mountinfo);
442 _mountinfo = NULL;
443 if (!_eeze_mount_mtab)
444 ERR("Could not parse /proc/self/mountinfo!");
445 else
446 {
447 ERR("Could not parse /etc/fstab!");
448 mnt_free_table(_eeze_mount_mtab);
449 }
450 _eeze_mount_mtab = _eeze_mount_fstab = NULL;
451 return EINA_FALSE;
452}
453
454EAPI void
455eeze_mount_tabs_unwatch(void)
456{
457 if (!_watching)
458 return;
459
460 _mountinfo_fdh = ecore_main_fd_handler_del(_mountinfo_fdh);
461 ecore_file_monitor_del(_fstab_mon);
462 _fstab_mon = NULL;
463 _watching = EINA_FALSE;
464}
465
466EAPI Eina_Bool
467eeze_mount_mtab_scan(void)
468{
469 libmnt_table *bak;
470
471 if (_watching)
472 return EINA_TRUE;
473
474 bak = _eeze_mount_tab_parse("/proc/self/mountinfo");
475 if (!bak)
476 goto error;
477 if (_eeze_mount_mtab)
478 {
479 mnt_free_table(_eeze_mount_mtab);
480 mnt_free_cache(_eeze_mount_mtab_cache);
481 }
482 _eeze_mount_mtab = bak;
483 _eeze_mount_mtab_cache = mnt_new_cache();
484 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
485
486 return EINA_TRUE;
487
488error:
489 return EINA_FALSE;
490}
491
492EAPI Eina_Bool
493eeze_mount_fstab_scan(void)
494{
495 libmnt_table *bak;
496 if (_watching)
497 return EINA_TRUE;
498
499 bak = _eeze_mount_tab_parse("/etc/fstab");
500 if (!bak)
501 goto error;
502 if (_eeze_mount_fstab)
503 {
504 mnt_free_table(_eeze_mount_fstab);
505 mnt_free_cache(_eeze_mount_fstab_cache);
506 }
507 _eeze_mount_fstab = bak;
508 _eeze_mount_fstab_cache = mnt_new_cache();
509 mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
510
511 return EINA_TRUE;
512
513error:
514 return EINA_FALSE;
515}
diff --git a/legacy/eeze/src/lib/eeze_disk_mount.c b/legacy/eeze/src/lib/eeze_disk_mount.c
index 5de67fb0f1..cbb57aed7c 100644
--- a/legacy/eeze/src/lib/eeze_disk_mount.c
+++ b/legacy/eeze/src/lib/eeze_disk_mount.c
@@ -79,6 +79,7 @@ _eeze_disk_mount_result_handler(void *data __UNUSED__, int type __UNUSED__, Ecor
79 disk->mounter = NULL; 79 disk->mounter = NULL;
80 if (!ev->exit_code) 80 if (!ev->exit_code)
81 { 81 {
82 disk->mounted = EINA_TRUE;
82 e = malloc(sizeof(Eeze_Event_Disk_Mount)); 83 e = malloc(sizeof(Eeze_Event_Disk_Mount));
83 EINA_SAFETY_ON_NULL_RETURN_VAL(e, ECORE_CALLBACK_RENEW); 84 EINA_SAFETY_ON_NULL_RETURN_VAL(e, ECORE_CALLBACK_RENEW);
84 e->disk = disk; 85 e->disk = disk;