Magellan Linux

Annotation of /trunk/mkinitrd-magellan/klibc/usr/kinit/do_mounts.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 4947 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 niro 532 #include <ctype.h>
2     #include <errno.h>
3     #include <fcntl.h>
4     #include <sys/mount.h>
5     #include <sys/stat.h>
6     #include <stdio.h>
7     #include <stdlib.h>
8     #include <string.h>
9     #include <unistd.h>
10     #include <alloca.h>
11     #include <inttypes.h>
12    
13     #include "do_mounts.h"
14     #include "kinit.h"
15     #include "fstype.h"
16     #include "zlib.h"
17    
18     /* Create the device node "name" */
19     int create_dev(const char *name, dev_t dev)
20     {
21     unlink(name);
22     return mknod(name, S_IFBLK | 0600, dev);
23     }
24    
25     /* mount a filesystem, possibly trying a set of different types */
26     const char *mount_block(const char *source, const char *target,
27     const char *type, unsigned long flags,
28     const void *data)
29     {
30     char *fslist, *p, *ep;
31     const char *rp;
32     ssize_t fsbytes;
33     int fd;
34    
35     if (type) {
36     DEBUG(("kinit: trying to mount %s on %s with type %s\n",
37     source, target, type));
38     int rv = mount(source, target, type, flags, data);
39     /* Mount readonly if necessary */
40     if (rv == -1 && errno == EACCES && !(flags & MS_RDONLY))
41     rv = mount(source, target, type, flags | MS_RDONLY,
42     data);
43     return rv ? NULL : type;
44     }
45    
46     /* If no type given, try to identify the type first; this
47     also takes care of specific ordering requirements, like
48     ext3 before ext2... */
49     fd = open(source, O_RDONLY);
50     if (fd >= 0) {
51     int err = identify_fs(fd, &type, NULL, 0);
52     close(fd);
53    
54     if (!err && type) {
55     DEBUG(("kinit: %s appears to be a %s filesystem\n",
56     source, type));
57     type = mount_block(source, target, type, flags, data);
58     if (type)
59     return type;
60     }
61     }
62    
63     DEBUG(("kinit: failed to identify filesystem %s, trying all\n",
64     source));
65    
66     fsbytes = readfile("/proc/filesystems", &fslist);
67    
68     errno = EINVAL;
69     if (fsbytes < 0)
70     return NULL;
71    
72     p = fslist;
73     ep = fslist + fsbytes;
74    
75     rp = NULL;
76    
77     while (p < ep) {
78     type = p;
79     p = strchr(p, '\n');
80     if (!p)
81     break;
82     *p++ = '\0';
83     if (*type != '\t') /* We can't mount a block device as a "nodev" fs */
84     continue;
85    
86     type++;
87     rp = mount_block(source, target, type, flags, data);
88     if (rp)
89     break;
90     if (errno != EINVAL)
91     break;
92     }
93    
94     free(fslist);
95     return rp;
96     }
97    
98     /* mount the root filesystem from a block device */
99     static int
100     mount_block_root(int argc, char *argv[], dev_t root_dev,
101     const char *type, unsigned long flags)
102     {
103     const char *data, *rp;
104    
105     data = get_arg(argc, argv, "rootflags=");
106     create_dev("/dev/root", root_dev);
107    
108     errno = 0;
109    
110     if (type) {
111     if ((rp = mount_block("/dev/root", "/root", type, flags, data)))
112     goto ok;
113     if (errno != EINVAL)
114     goto bad;
115     }
116    
117     if (!errno
118     && (rp = mount_block("/dev/root", "/root", NULL, flags, data)))
119     goto ok;
120    
121     bad:
122     if (errno != EINVAL) {
123     /*
124     * Allow the user to distinguish between failed open
125     * and bad superblock on root device.
126     */
127     fprintf(stderr, "%s: Cannot open root device %s\n",
128     progname, bdevname(root_dev));
129     return -errno;
130     } else {
131     fprintf(stderr, "%s: Unable to mount root fs on device %s\n",
132     progname, bdevname(root_dev));
133     return -ESRCH;
134     }
135    
136     ok:
137     printf("%s: Mounted root (%s filesystem)%s.\n",
138     progname, rp, (flags & MS_RDONLY) ? " readonly" : "");
139     return 0;
140     }
141    
142     int
143     mount_root(int argc, char *argv[], dev_t root_dev, const char *root_dev_name)
144     {
145     unsigned long flags = MS_RDONLY | MS_VERBOSE;
146     int ret;
147     const char *type = get_arg(argc, argv, "rootfstype=");
148    
149     if (get_flag(argc, argv, "rw") > get_flag(argc, argv, "ro")) {
150     DEBUG(("kinit: mounting root rw\n"));
151     flags &= ~MS_RDONLY;
152     }
153    
154     if (type) {
155     if (!strcmp(type, "nfs"))
156     root_dev = Root_NFS;
157     else if (!strcmp(type, "jffs2") && !major(root_dev))
158     root_dev = Root_MTD;
159     }
160    
161     switch (root_dev) {
162     case Root_NFS:
163     ret = mount_nfs_root(argc, argv, flags);
164     break;
165     case Root_MTD:
166     ret = mount_mtd_root(argc, argv, root_dev_name, type, flags);
167     break;
168     default:
169     ret = mount_block_root(argc, argv, root_dev, type, flags);
170     break;
171     }
172    
173     if (!ret)
174     chdir("/root");
175    
176     return ret;
177     }
178    
179     int do_mounts(int argc, char *argv[])
180     {
181     const char *root_dev_name = get_arg(argc, argv, "root=");
182     const char *root_delay = get_arg(argc, argv, "rootdelay=");
183     const char *load_ramdisk = get_arg(argc, argv, "load_ramdisk=");
184     dev_t root_dev = 0;
185    
186     DEBUG(("kinit: do_mounts\n"));
187    
188     if (root_delay) {
189     int delay = atoi(root_delay);
190     fprintf(stderr, "Waiting %d s before mounting root device...\n",
191     delay);
192     sleep(delay);
193     }
194    
195     md_run(argc, argv);
196    
197     if (root_dev_name) {
198     root_dev = name_to_dev_t(root_dev_name);
199     } else if (get_arg(argc, argv, "nfsroot=") ||
200     get_arg(argc, argv, "nfsaddrs=")) {
201     root_dev = Root_NFS;
202     } else {
203     long rootdev;
204     getintfile("/proc/sys/kernel/real-root-dev", &rootdev);
205     root_dev = (dev_t) rootdev;
206     }
207    
208     DEBUG(("kinit: root_dev = %s\n", bdevname(root_dev)));
209    
210     if (initrd_load(argc, argv, root_dev)) {
211     DEBUG(("initrd loaded\n"));
212     return 0;
213     }
214    
215     if (load_ramdisk && atoi(load_ramdisk)) {
216     if (ramdisk_load(argc, argv, root_dev))
217     root_dev = Root_RAM0;
218     }
219    
220     return mount_root(argc, argv, root_dev, root_dev_name);
221     }