annotate toys/lsb/umount.c @ 1183:0752b2d58909 draft

Rename xmsprintf() to just xmprintf(). Partly because there's no supplied target string ala sprintf, and partly because I can never remember what order the m and s go in.
author Rob Landley <rob@landley.net>
date Thu, 16 Jan 2014 09:26:50 -0600
parents ac4a0cde89c2
children 4d898affda0c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1044
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
1 /* umount.c - Unmount a mount point.
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
2 *
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
3 * Copyright 2012 Rob Landley <rob@landley.net>
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
4 *
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
5 * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/umount.html
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
6 *
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
7 * Note: -n (/etc/mtab) is obsolete, /proc/mounts replaced it. Neither chroot
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
8 * nor per-process mount namespaces can work sanely with mtab. The kernel
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
9 * tracks mount points now, a userspace application can't do so anymore.
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
10
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
11 USE_UMOUNT(NEWTOY(umount, "ndDflrat*v", TOYFLAG_BIN|TOYFLAG_STAYROOT))
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
12
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
13 config UMOUNT
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
14 bool "umount"
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
15 default y
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
16 help
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
17 usage: umount [-a [-t TYPE[,TYPE...]]] [-vrfD] [DIR...]
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
18
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
19 Unmount the listed filesystems.
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
20
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
21 -a Unmount all mounts in /proc/mounts instead of command line list
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
22 -t Restrict "all" to mounts of TYPE (or use "noTYPE" to skip)
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
23 -D Don't free loopback device(s).
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
24 -f Force unmount.
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
25 -l Lazy unmount (detach from filesystem now, close when last user does).
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
26 -r Remount read only if unmounting fails.
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
27 -v Verbose
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
28 */
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
29
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
30 #define FOR_umount
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
31 #include "toys.h"
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
32
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
33 GLOBALS(
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
34 struct arg_list *t;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
35
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
36 char *types;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
37 )
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
38
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
39 // todo
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
40 // borrow df code to identify filesystem?
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
41 // umount -a from fstab
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
42 // umount when getpid() not 0, according to fstab
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
43 // lookup mount: losetup -d, bind, file, block
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
44
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
45 // TODO
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
46 // loopback delete
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
47 // fstab -o user
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
48
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
49 // Realloc *old with oldstring,newstring
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
50
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
51 void comma_collate(char **old, char *new)
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
52 {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
53 char *temp, *atold = *old;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
54
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
55 // Only add a comma if old string didn't end with one
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
56 if (atold && *atold) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
57 char *comma = ",";
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
58
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
59 if (atold[strlen(atold)-1] == ',') comma = "";
1183
0752b2d58909 Rename xmsprintf() to just xmprintf().
Rob Landley <rob@landley.net>
parents: 1150
diff changeset
60 temp = xmprintf("%s%s%s", atold, comma, new);
1044
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
61 } else temp = xstrdup(new);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
62 free (atold);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
63 *old = temp;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
64 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
65
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
66 void arg_comma_collate(char **old, struct arg_list *arg)
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
67 {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
68 while (arg) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
69 comma_collate(old, arg->arg);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
70 arg = arg->next;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
71 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
72 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
73
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
74 char *comma_iterate(char **list, int *len)
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
75 {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
76 char *start = *list, *end;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
77
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
78 if (!*list) return 0;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
79 if (!(end = strchr(*list, ','))) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
80 *len = strlen(*list);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
81 *list = 0;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
82 } else *list += (*len = end-start)+1;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
83
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
84 return start;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
85 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
86
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
87 static void do_umount(char *dir, int flags)
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
88 {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
89 if (!umount2(dir, flags)) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
90 if (toys.optflags & FLAG_v) printf("%s unmounted", dir);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
91 return;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
92 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
93 if (toys.optflags & FLAG_r) {
1150
ac4a0cde89c2 Don't permute toys.optargs, cleanup code (xexec()) can free it.
Rob Landley <rob@landley.net>
parents: 1044
diff changeset
94 if (!mount("", dir, "", MS_REMOUNT|MS_RDONLY, "")) {
1044
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
95 if (toys.optflags & FLAG_v) printf("%s remounted ro", dir);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
96 return;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
97 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
98 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
99 perror_msg("%s", dir);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
100 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
101
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
102 void umount_main(void)
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
103 {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
104 int flags=0;
1150
ac4a0cde89c2 Don't permute toys.optargs, cleanup code (xexec()) can free it.
Rob Landley <rob@landley.net>
parents: 1044
diff changeset
105 char **optargs;
1044
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
106
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
107 if (!toys.optc && !(toys.optflags & FLAG_a))
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
108 error_exit("Need 1 arg or -a");
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
109
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
110 if (toys.optflags & FLAG_f) flags |= MNT_FORCE;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
111 if (toys.optflags & FLAG_l) flags |= MNT_DETACH;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
112
1150
ac4a0cde89c2 Don't permute toys.optargs, cleanup code (xexec()) can free it.
Rob Landley <rob@landley.net>
parents: 1044
diff changeset
113 for (optargs = toys.optargs; *optargs; optargs++) do_umount(*optargs, flags);
1044
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
114
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
115 if (toys.optflags & FLAG_a) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
116 struct mtab_list *mlsave, *ml;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
117 char *typestr = 0;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
118
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
119 if (TT.t) arg_comma_collate(&typestr, TT.t);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
120
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
121 // Loop through mounted filesystems
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
122 for (mlsave = ml = xgetmountlist(0); ml; ml = ml->next) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
123 if (TT.t) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
124 char *type, *types = typestr;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
125 int len, skip = strncmp(types, "no", 2);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
126
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
127 // Loop through -t filters
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
128 for (;;) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
129 if (!(type = comma_iterate(&types, &len))) break;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
130 if (!skip) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
131 if (strncmp(type, "no", 2)) error_exit("bad -t");
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
132 if (!strncmp(type+2, ml->type, len-2)) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
133 skip = 1;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
134 break;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
135 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
136 } else if (!strncmp(type, ml->type, len) && !ml->type[len]) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
137 skip = 0;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
138 break;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
139 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
140 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
141 if (skip) continue;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
142 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
143 do_umount(ml->dir, flags);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
144 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
145 if (CFG_TOYBOX_FREE) {
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
146 free(typestr);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
147 llist_traverse(mlsave, free);
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
148 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
149
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
150 return;
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
151 }
e62df9eb3661 First pass at umount, not quite done yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
152 }