Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/init.h>
0003 #include <linux/async.h>
0004 #include <linux/fs.h>
0005 #include <linux/slab.h>
0006 #include <linux/types.h>
0007 #include <linux/fcntl.h>
0008 #include <linux/delay.h>
0009 #include <linux/string.h>
0010 #include <linux/dirent.h>
0011 #include <linux/syscalls.h>
0012 #include <linux/utime.h>
0013 #include <linux/file.h>
0014 #include <linux/memblock.h>
0015 #include <linux/mm.h>
0016 #include <linux/namei.h>
0017 #include <linux/init_syscalls.h>
0018 #include <linux/task_work.h>
0019 #include <linux/umh.h>
0020 
0021 static __initdata bool csum_present;
0022 static __initdata u32 io_csum;
0023 
0024 static ssize_t __init xwrite(struct file *file, const unsigned char *p,
0025         size_t count, loff_t *pos)
0026 {
0027     ssize_t out = 0;
0028 
0029     /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */
0030     while (count) {
0031         ssize_t rv = kernel_write(file, p, count, pos);
0032 
0033         if (rv < 0) {
0034             if (rv == -EINTR || rv == -EAGAIN)
0035                 continue;
0036             return out ? out : rv;
0037         } else if (rv == 0)
0038             break;
0039 
0040         if (csum_present) {
0041             ssize_t i;
0042 
0043             for (i = 0; i < rv; i++)
0044                 io_csum += p[i];
0045         }
0046 
0047         p += rv;
0048         out += rv;
0049         count -= rv;
0050     }
0051 
0052     return out;
0053 }
0054 
0055 static __initdata char *message;
0056 static void __init error(char *x)
0057 {
0058     if (!message)
0059         message = x;
0060 }
0061 
0062 static void panic_show_mem(const char *fmt, ...)
0063 {
0064     va_list args;
0065 
0066     show_mem(0, NULL);
0067     va_start(args, fmt);
0068     panic(fmt, args);
0069     va_end(args);
0070 }
0071 
0072 /* link hash */
0073 
0074 #define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
0075 
0076 static __initdata struct hash {
0077     int ino, minor, major;
0078     umode_t mode;
0079     struct hash *next;
0080     char name[N_ALIGN(PATH_MAX)];
0081 } *head[32];
0082 
0083 static inline int hash(int major, int minor, int ino)
0084 {
0085     unsigned long tmp = ino + minor + (major << 3);
0086     tmp += tmp >> 5;
0087     return tmp & 31;
0088 }
0089 
0090 static char __init *find_link(int major, int minor, int ino,
0091                   umode_t mode, char *name)
0092 {
0093     struct hash **p, *q;
0094     for (p = head + hash(major, minor, ino); *p; p = &(*p)->next) {
0095         if ((*p)->ino != ino)
0096             continue;
0097         if ((*p)->minor != minor)
0098             continue;
0099         if ((*p)->major != major)
0100             continue;
0101         if (((*p)->mode ^ mode) & S_IFMT)
0102             continue;
0103         return (*p)->name;
0104     }
0105     q = kmalloc(sizeof(struct hash), GFP_KERNEL);
0106     if (!q)
0107         panic_show_mem("can't allocate link hash entry");
0108     q->major = major;
0109     q->minor = minor;
0110     q->ino = ino;
0111     q->mode = mode;
0112     strcpy(q->name, name);
0113     q->next = NULL;
0114     *p = q;
0115     return NULL;
0116 }
0117 
0118 static void __init free_hash(void)
0119 {
0120     struct hash **p, *q;
0121     for (p = head; p < head + 32; p++) {
0122         while (*p) {
0123             q = *p;
0124             *p = q->next;
0125             kfree(q);
0126         }
0127     }
0128 }
0129 
0130 #ifdef CONFIG_INITRAMFS_PRESERVE_MTIME
0131 static void __init do_utime(char *filename, time64_t mtime)
0132 {
0133     struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } };
0134     init_utimes(filename, t);
0135 }
0136 
0137 static void __init do_utime_path(const struct path *path, time64_t mtime)
0138 {
0139     struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } };
0140     vfs_utimes(path, t);
0141 }
0142 
0143 static __initdata LIST_HEAD(dir_list);
0144 struct dir_entry {
0145     struct list_head list;
0146     time64_t mtime;
0147     char name[];
0148 };
0149 
0150 static void __init dir_add(const char *name, time64_t mtime)
0151 {
0152     size_t nlen = strlen(name) + 1;
0153     struct dir_entry *de;
0154 
0155     de = kmalloc(sizeof(struct dir_entry) + nlen, GFP_KERNEL);
0156     if (!de)
0157         panic_show_mem("can't allocate dir_entry buffer");
0158     INIT_LIST_HEAD(&de->list);
0159     strscpy(de->name, name, nlen);
0160     de->mtime = mtime;
0161     list_add(&de->list, &dir_list);
0162 }
0163 
0164 static void __init dir_utime(void)
0165 {
0166     struct dir_entry *de, *tmp;
0167     list_for_each_entry_safe(de, tmp, &dir_list, list) {
0168         list_del(&de->list);
0169         do_utime(de->name, de->mtime);
0170         kfree(de);
0171     }
0172 }
0173 #else
0174 static void __init do_utime(char *filename, time64_t mtime) {}
0175 static void __init do_utime_path(const struct path *path, time64_t mtime) {}
0176 static void __init dir_add(const char *name, time64_t mtime) {}
0177 static void __init dir_utime(void) {}
0178 #endif
0179 
0180 static __initdata time64_t mtime;
0181 
0182 /* cpio header parsing */
0183 
0184 static __initdata unsigned long ino, major, minor, nlink;
0185 static __initdata umode_t mode;
0186 static __initdata unsigned long body_len, name_len;
0187 static __initdata uid_t uid;
0188 static __initdata gid_t gid;
0189 static __initdata unsigned rdev;
0190 static __initdata u32 hdr_csum;
0191 
0192 static void __init parse_header(char *s)
0193 {
0194     unsigned long parsed[13];
0195     char buf[9];
0196     int i;
0197 
0198     buf[8] = '\0';
0199     for (i = 0, s += 6; i < 13; i++, s += 8) {
0200         memcpy(buf, s, 8);
0201         parsed[i] = simple_strtoul(buf, NULL, 16);
0202     }
0203     ino = parsed[0];
0204     mode = parsed[1];
0205     uid = parsed[2];
0206     gid = parsed[3];
0207     nlink = parsed[4];
0208     mtime = parsed[5]; /* breaks in y2106 */
0209     body_len = parsed[6];
0210     major = parsed[7];
0211     minor = parsed[8];
0212     rdev = new_encode_dev(MKDEV(parsed[9], parsed[10]));
0213     name_len = parsed[11];
0214     hdr_csum = parsed[12];
0215 }
0216 
0217 /* FSM */
0218 
0219 static __initdata enum state {
0220     Start,
0221     Collect,
0222     GotHeader,
0223     SkipIt,
0224     GotName,
0225     CopyFile,
0226     GotSymlink,
0227     Reset
0228 } state, next_state;
0229 
0230 static __initdata char *victim;
0231 static unsigned long byte_count __initdata;
0232 static __initdata loff_t this_header, next_header;
0233 
0234 static inline void __init eat(unsigned n)
0235 {
0236     victim += n;
0237     this_header += n;
0238     byte_count -= n;
0239 }
0240 
0241 static __initdata char *collected;
0242 static long remains __initdata;
0243 static __initdata char *collect;
0244 
0245 static void __init read_into(char *buf, unsigned size, enum state next)
0246 {
0247     if (byte_count >= size) {
0248         collected = victim;
0249         eat(size);
0250         state = next;
0251     } else {
0252         collect = collected = buf;
0253         remains = size;
0254         next_state = next;
0255         state = Collect;
0256     }
0257 }
0258 
0259 static __initdata char *header_buf, *symlink_buf, *name_buf;
0260 
0261 static int __init do_start(void)
0262 {
0263     read_into(header_buf, 110, GotHeader);
0264     return 0;
0265 }
0266 
0267 static int __init do_collect(void)
0268 {
0269     unsigned long n = remains;
0270     if (byte_count < n)
0271         n = byte_count;
0272     memcpy(collect, victim, n);
0273     eat(n);
0274     collect += n;
0275     if ((remains -= n) != 0)
0276         return 1;
0277     state = next_state;
0278     return 0;
0279 }
0280 
0281 static int __init do_header(void)
0282 {
0283     if (!memcmp(collected, "070701", 6)) {
0284         csum_present = false;
0285     } else if (!memcmp(collected, "070702", 6)) {
0286         csum_present = true;
0287     } else {
0288         if (memcmp(collected, "070707", 6) == 0)
0289             error("incorrect cpio method used: use -H newc option");
0290         else
0291             error("no cpio magic");
0292         return 1;
0293     }
0294     parse_header(collected);
0295     next_header = this_header + N_ALIGN(name_len) + body_len;
0296     next_header = (next_header + 3) & ~3;
0297     state = SkipIt;
0298     if (name_len <= 0 || name_len > PATH_MAX)
0299         return 0;
0300     if (S_ISLNK(mode)) {
0301         if (body_len > PATH_MAX)
0302             return 0;
0303         collect = collected = symlink_buf;
0304         remains = N_ALIGN(name_len) + body_len;
0305         next_state = GotSymlink;
0306         state = Collect;
0307         return 0;
0308     }
0309     if (S_ISREG(mode) || !body_len)
0310         read_into(name_buf, N_ALIGN(name_len), GotName);
0311     return 0;
0312 }
0313 
0314 static int __init do_skip(void)
0315 {
0316     if (this_header + byte_count < next_header) {
0317         eat(byte_count);
0318         return 1;
0319     } else {
0320         eat(next_header - this_header);
0321         state = next_state;
0322         return 0;
0323     }
0324 }
0325 
0326 static int __init do_reset(void)
0327 {
0328     while (byte_count && *victim == '\0')
0329         eat(1);
0330     if (byte_count && (this_header & 3))
0331         error("broken padding");
0332     return 1;
0333 }
0334 
0335 static void __init clean_path(char *path, umode_t fmode)
0336 {
0337     struct kstat st;
0338 
0339     if (!init_stat(path, &st, AT_SYMLINK_NOFOLLOW) &&
0340         (st.mode ^ fmode) & S_IFMT) {
0341         if (S_ISDIR(st.mode))
0342             init_rmdir(path);
0343         else
0344             init_unlink(path);
0345     }
0346 }
0347 
0348 static int __init maybe_link(void)
0349 {
0350     if (nlink >= 2) {
0351         char *old = find_link(major, minor, ino, mode, collected);
0352         if (old) {
0353             clean_path(collected, 0);
0354             return (init_link(old, collected) < 0) ? -1 : 1;
0355         }
0356     }
0357     return 0;
0358 }
0359 
0360 static __initdata struct file *wfile;
0361 static __initdata loff_t wfile_pos;
0362 
0363 static int __init do_name(void)
0364 {
0365     state = SkipIt;
0366     next_state = Reset;
0367     if (strcmp(collected, "TRAILER!!!") == 0) {
0368         free_hash();
0369         return 0;
0370     }
0371     clean_path(collected, mode);
0372     if (S_ISREG(mode)) {
0373         int ml = maybe_link();
0374         if (ml >= 0) {
0375             int openflags = O_WRONLY|O_CREAT;
0376             if (ml != 1)
0377                 openflags |= O_TRUNC;
0378             wfile = filp_open(collected, openflags, mode);
0379             if (IS_ERR(wfile))
0380                 return 0;
0381             wfile_pos = 0;
0382             io_csum = 0;
0383 
0384             vfs_fchown(wfile, uid, gid);
0385             vfs_fchmod(wfile, mode);
0386             if (body_len)
0387                 vfs_truncate(&wfile->f_path, body_len);
0388             state = CopyFile;
0389         }
0390     } else if (S_ISDIR(mode)) {
0391         init_mkdir(collected, mode);
0392         init_chown(collected, uid, gid, 0);
0393         init_chmod(collected, mode);
0394         dir_add(collected, mtime);
0395     } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
0396            S_ISFIFO(mode) || S_ISSOCK(mode)) {
0397         if (maybe_link() == 0) {
0398             init_mknod(collected, mode, rdev);
0399             init_chown(collected, uid, gid, 0);
0400             init_chmod(collected, mode);
0401             do_utime(collected, mtime);
0402         }
0403     }
0404     return 0;
0405 }
0406 
0407 static int __init do_copy(void)
0408 {
0409     if (byte_count >= body_len) {
0410         if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len)
0411             error("write error");
0412 
0413         do_utime_path(&wfile->f_path, mtime);
0414         fput(wfile);
0415         if (csum_present && io_csum != hdr_csum)
0416             error("bad data checksum");
0417         eat(body_len);
0418         state = SkipIt;
0419         return 0;
0420     } else {
0421         if (xwrite(wfile, victim, byte_count, &wfile_pos) != byte_count)
0422             error("write error");
0423         body_len -= byte_count;
0424         eat(byte_count);
0425         return 1;
0426     }
0427 }
0428 
0429 static int __init do_symlink(void)
0430 {
0431     collected[N_ALIGN(name_len) + body_len] = '\0';
0432     clean_path(collected, 0);
0433     init_symlink(collected + N_ALIGN(name_len), collected);
0434     init_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW);
0435     do_utime(collected, mtime);
0436     state = SkipIt;
0437     next_state = Reset;
0438     return 0;
0439 }
0440 
0441 static __initdata int (*actions[])(void) = {
0442     [Start]     = do_start,
0443     [Collect]   = do_collect,
0444     [GotHeader] = do_header,
0445     [SkipIt]    = do_skip,
0446     [GotName]   = do_name,
0447     [CopyFile]  = do_copy,
0448     [GotSymlink]    = do_symlink,
0449     [Reset]     = do_reset,
0450 };
0451 
0452 static long __init write_buffer(char *buf, unsigned long len)
0453 {
0454     byte_count = len;
0455     victim = buf;
0456 
0457     while (!actions[state]())
0458         ;
0459     return len - byte_count;
0460 }
0461 
0462 static long __init flush_buffer(void *bufv, unsigned long len)
0463 {
0464     char *buf = (char *) bufv;
0465     long written;
0466     long origLen = len;
0467     if (message)
0468         return -1;
0469     while ((written = write_buffer(buf, len)) < len && !message) {
0470         char c = buf[written];
0471         if (c == '0') {
0472             buf += written;
0473             len -= written;
0474             state = Start;
0475         } else if (c == 0) {
0476             buf += written;
0477             len -= written;
0478             state = Reset;
0479         } else
0480             error("junk within compressed archive");
0481     }
0482     return origLen;
0483 }
0484 
0485 static unsigned long my_inptr; /* index of next byte to be processed in inbuf */
0486 
0487 #include <linux/decompress/generic.h>
0488 
0489 static char * __init unpack_to_rootfs(char *buf, unsigned long len)
0490 {
0491     long written;
0492     decompress_fn decompress;
0493     const char *compress_name;
0494     static __initdata char msg_buf[64];
0495 
0496     header_buf = kmalloc(110, GFP_KERNEL);
0497     symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
0498     name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
0499 
0500     if (!header_buf || !symlink_buf || !name_buf)
0501         panic_show_mem("can't allocate buffers");
0502 
0503     state = Start;
0504     this_header = 0;
0505     message = NULL;
0506     while (!message && len) {
0507         loff_t saved_offset = this_header;
0508         if (*buf == '0' && !(this_header & 3)) {
0509             state = Start;
0510             written = write_buffer(buf, len);
0511             buf += written;
0512             len -= written;
0513             continue;
0514         }
0515         if (!*buf) {
0516             buf++;
0517             len--;
0518             this_header++;
0519             continue;
0520         }
0521         this_header = 0;
0522         decompress = decompress_method(buf, len, &compress_name);
0523         pr_debug("Detected %s compressed data\n", compress_name);
0524         if (decompress) {
0525             int res = decompress(buf, len, NULL, flush_buffer, NULL,
0526                    &my_inptr, error);
0527             if (res)
0528                 error("decompressor failed");
0529         } else if (compress_name) {
0530             if (!message) {
0531                 snprintf(msg_buf, sizeof msg_buf,
0532                      "compression method %s not configured",
0533                      compress_name);
0534                 message = msg_buf;
0535             }
0536         } else
0537             error("invalid magic at start of compressed archive");
0538         if (state != Reset)
0539             error("junk at the end of compressed archive");
0540         this_header = saved_offset + my_inptr;
0541         buf += my_inptr;
0542         len -= my_inptr;
0543     }
0544     dir_utime();
0545     kfree(name_buf);
0546     kfree(symlink_buf);
0547     kfree(header_buf);
0548     return message;
0549 }
0550 
0551 static int __initdata do_retain_initrd;
0552 
0553 static int __init retain_initrd_param(char *str)
0554 {
0555     if (*str)
0556         return 0;
0557     do_retain_initrd = 1;
0558     return 1;
0559 }
0560 __setup("retain_initrd", retain_initrd_param);
0561 
0562 #ifdef CONFIG_ARCH_HAS_KEEPINITRD
0563 static int __init keepinitrd_setup(char *__unused)
0564 {
0565     do_retain_initrd = 1;
0566     return 1;
0567 }
0568 __setup("keepinitrd", keepinitrd_setup);
0569 #endif
0570 
0571 static bool __initdata initramfs_async = true;
0572 static int __init initramfs_async_setup(char *str)
0573 {
0574     strtobool(str, &initramfs_async);
0575     return 1;
0576 }
0577 __setup("initramfs_async=", initramfs_async_setup);
0578 
0579 extern char __initramfs_start[];
0580 extern unsigned long __initramfs_size;
0581 #include <linux/initrd.h>
0582 #include <linux/kexec.h>
0583 
0584 void __init reserve_initrd_mem(void)
0585 {
0586     phys_addr_t start;
0587     unsigned long size;
0588 
0589     /* Ignore the virtul address computed during device tree parsing */
0590     initrd_start = initrd_end = 0;
0591 
0592     if (!phys_initrd_size)
0593         return;
0594     /*
0595      * Round the memory region to page boundaries as per free_initrd_mem()
0596      * This allows us to detect whether the pages overlapping the initrd
0597      * are in use, but more importantly, reserves the entire set of pages
0598      * as we don't want these pages allocated for other purposes.
0599      */
0600     start = round_down(phys_initrd_start, PAGE_SIZE);
0601     size = phys_initrd_size + (phys_initrd_start - start);
0602     size = round_up(size, PAGE_SIZE);
0603 
0604     if (!memblock_is_region_memory(start, size)) {
0605         pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region",
0606                (u64)start, size);
0607         goto disable;
0608     }
0609 
0610     if (memblock_is_region_reserved(start, size)) {
0611         pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region\n",
0612                (u64)start, size);
0613         goto disable;
0614     }
0615 
0616     memblock_reserve(start, size);
0617     /* Now convert initrd to virtual addresses */
0618     initrd_start = (unsigned long)__va(phys_initrd_start);
0619     initrd_end = initrd_start + phys_initrd_size;
0620     initrd_below_start_ok = 1;
0621 
0622     return;
0623 disable:
0624     pr_cont(" - disabling initrd\n");
0625     initrd_start = 0;
0626     initrd_end = 0;
0627 }
0628 
0629 void __weak __init free_initrd_mem(unsigned long start, unsigned long end)
0630 {
0631 #ifdef CONFIG_ARCH_KEEP_MEMBLOCK
0632     unsigned long aligned_start = ALIGN_DOWN(start, PAGE_SIZE);
0633     unsigned long aligned_end = ALIGN(end, PAGE_SIZE);
0634 
0635     memblock_free((void *)aligned_start, aligned_end - aligned_start);
0636 #endif
0637 
0638     free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
0639             "initrd");
0640 }
0641 
0642 #ifdef CONFIG_KEXEC_CORE
0643 static bool __init kexec_free_initrd(void)
0644 {
0645     unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
0646     unsigned long crashk_end   = (unsigned long)__va(crashk_res.end);
0647 
0648     /*
0649      * If the initrd region is overlapped with crashkernel reserved region,
0650      * free only memory that is not part of crashkernel region.
0651      */
0652     if (initrd_start >= crashk_end || initrd_end <= crashk_start)
0653         return false;
0654 
0655     /*
0656      * Initialize initrd memory region since the kexec boot does not do.
0657      */
0658     memset((void *)initrd_start, 0, initrd_end - initrd_start);
0659     if (initrd_start < crashk_start)
0660         free_initrd_mem(initrd_start, crashk_start);
0661     if (initrd_end > crashk_end)
0662         free_initrd_mem(crashk_end, initrd_end);
0663     return true;
0664 }
0665 #else
0666 static inline bool kexec_free_initrd(void)
0667 {
0668     return false;
0669 }
0670 #endif /* CONFIG_KEXEC_CORE */
0671 
0672 #ifdef CONFIG_BLK_DEV_RAM
0673 static void __init populate_initrd_image(char *err)
0674 {
0675     ssize_t written;
0676     struct file *file;
0677     loff_t pos = 0;
0678 
0679     unpack_to_rootfs(__initramfs_start, __initramfs_size);
0680 
0681     printk(KERN_INFO "rootfs image is not initramfs (%s); looks like an initrd\n",
0682             err);
0683     file = filp_open("/initrd.image", O_WRONLY | O_CREAT, 0700);
0684     if (IS_ERR(file))
0685         return;
0686 
0687     written = xwrite(file, (char *)initrd_start, initrd_end - initrd_start,
0688             &pos);
0689     if (written != initrd_end - initrd_start)
0690         pr_err("/initrd.image: incomplete write (%zd != %ld)\n",
0691                written, initrd_end - initrd_start);
0692     fput(file);
0693 }
0694 #endif /* CONFIG_BLK_DEV_RAM */
0695 
0696 static void __init do_populate_rootfs(void *unused, async_cookie_t cookie)
0697 {
0698     /* Load the built in initramfs */
0699     char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
0700     if (err)
0701         panic_show_mem("%s", err); /* Failed to decompress INTERNAL initramfs */
0702 
0703     if (!initrd_start || IS_ENABLED(CONFIG_INITRAMFS_FORCE))
0704         goto done;
0705 
0706     if (IS_ENABLED(CONFIG_BLK_DEV_RAM))
0707         printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n");
0708     else
0709         printk(KERN_INFO "Unpacking initramfs...\n");
0710 
0711     err = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start);
0712     if (err) {
0713 #ifdef CONFIG_BLK_DEV_RAM
0714         populate_initrd_image(err);
0715 #else
0716         printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
0717 #endif
0718     }
0719 
0720 done:
0721     /*
0722      * If the initrd region is overlapped with crashkernel reserved region,
0723      * free only memory that is not part of crashkernel region.
0724      */
0725     if (!do_retain_initrd && initrd_start && !kexec_free_initrd())
0726         free_initrd_mem(initrd_start, initrd_end);
0727     initrd_start = 0;
0728     initrd_end = 0;
0729 
0730     flush_delayed_fput();
0731     task_work_run();
0732 }
0733 
0734 static ASYNC_DOMAIN_EXCLUSIVE(initramfs_domain);
0735 static async_cookie_t initramfs_cookie;
0736 
0737 void wait_for_initramfs(void)
0738 {
0739     if (!initramfs_cookie) {
0740         /*
0741          * Something before rootfs_initcall wants to access
0742          * the filesystem/initramfs. Probably a bug. Make a
0743          * note, avoid deadlocking the machine, and let the
0744          * caller's access fail as it used to.
0745          */
0746         pr_warn_once("wait_for_initramfs() called before rootfs_initcalls\n");
0747         return;
0748     }
0749     async_synchronize_cookie_domain(initramfs_cookie + 1, &initramfs_domain);
0750 }
0751 EXPORT_SYMBOL_GPL(wait_for_initramfs);
0752 
0753 static int __init populate_rootfs(void)
0754 {
0755     initramfs_cookie = async_schedule_domain(do_populate_rootfs, NULL,
0756                          &initramfs_domain);
0757     usermodehelper_enable();
0758     if (!initramfs_async)
0759         wait_for_initramfs();
0760     return 0;
0761 }
0762 rootfs_initcall(populate_rootfs);