随笔记录

dell-recovery_bootloader

  1. 安装时调用 build-factory.sh(在postinst中),该脚本虽然在这里被调用,但该脚本属于dell-recovery_all。
#!/bin/sh -e

. /usr/share/debconf/confmodule

case "$1" in
  configure)
    /usr/share/dell/grub/build-factory.sh                                                                                                                                                 
  ;;  
  abort-upgrade|abort-remove|abort-deconfigure)
  ;;  
  *)  
    echo "postinst called with unknown argument \`$1'" >&2
    exit 1
  ;;  
esac

# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.



exit 0
build-factory.sh

[ -n "$TARGET" ]         || TARGET=/var/lib/dell-recovery
[ -n "$SOURCE_GRUBDIR" ] || SOURCE_GRUBDIR=/usr/share/dell/grub
[ -n "$TARGET_GRUBCFG" ] || TARGET_GRUBCFG=$TARGET/grub.cfg
echo "Creating factory grub.cfg"                                                                                                                                                               
OS=$(lsb_release -s -d)
sed "s,#OS#,$OS,; /#UUID#/d" \
        $SOURCE_GRUBDIR/recovery_partition.cfg \
        > $TARGET_GRUBCFG

在/usr/share/dell/grub 生成一个grub.cfg

dell-recovery_casper

.
├── DEBIAN
│   ├── control
│   └── md5sums
└── usr
    └── share
        ├── doc
        │   └── dell-recovery-casper
        │       ├── changelog.gz
        │       └── copyright
        └── initramfs-tools
            ├── hooks
            │   └── dell-bootstrap -> ../../dell/casper/hooks/dell-bootstrap
            └── scripts
                └── casper-bottom
                    └── 99dell_bootstrap -> ../../../dell/casper/scripts/99dell_bootstrap

目录结构,向initramfs-tools中添加2个脚本(这两个脚本都在dell-recovery_all中)
其中dell-bootstrap是在生成initramfs的过程中被调用;99dell_bootstrap是放在initramfs中(即放在initrd中),在时机-----casper-bootom执行。

99dell_bootstrap

PREREQ=""
DESCRIPTION="Running DELL bootstrap..."

prereqs ()
{
    echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
    prereqs
    exit 0
    ;;
esac

. /scripts/casper-functions
load_confmodule

log_begin_msg "$DESCRIPTION"

export DEBIAN_HAS_FRONTEND=
export DEBCONF_REDIR=
export DEBIAN_FRONTEND=noninteractive

# Early emergency installer fix
if [ -e /root/cdrom/scripts/emergency.sh ]; then
    . /root/cdrom/scripts/emergency.sh
elif [ -e /root/isodevice/scripts/emergency.sh ]; then
    . /root/isodevice/scripts/emergency.sh
fi

if [ -d /root/isodevice ]; then
    if [ -f /root/isodevice/.disk/info.recovery -a ! -f /root/isodevice/.disk/info ]; then
    mount -o remount,rw /root/isodevice
    cp /root/isodevice/.disk/info.recovery /root/isodevice/.disk/info
    mount -o remount,ro /root/isodevice
    fi
elif [ -f /root/cdrom/.disk/info.recovery -a ! -f /root/cdrom/.disk/info ]; then
    mount -o remount,rw /root/cdrom
    cp /root/cdrom/.disk/info.recovery /root/cdrom/.disk/info
    mount -o remount,ro /root/cdrom
fi

#Force ubiquity to run in automatic regardless if there are ubiquity options in /proc/cmdline (except single user mode) 
if ! grep -q "single" /proc/cmdline 2>&1 >/dev/null; then
    sed -i "s/ubiquity=\$/ubiquity=1/; s/\$automatic\ \$choose/--automatic/" /root/etc/init/ubiquity.conf
fi
#if they use a ubiquity icon it needs to run in automatic
if [ -f /root/etc/init.d/casper ]; then
    sed -i "s/prompt=1$/prompt=/;" /root/etc/init.d/casper
fi
sed -i "s/Exec=ubiquity/Exec=ubiquity --automatic/" /root/usr/share/applications/ubiquity-gtkui.desktop 2>/dev/null || true

#Build custom pool (static and dynamic)
if [ ! -x /root/usr/share/dell/scripts/pool.sh ]; then
    mkdir -p /root/usr/share/dell/scripts/
    cp /scripts/pool.sh /root/usr/share/dell/scripts/
fi
chroot /root /usr/share/dell/scripts/pool.sh

#install if not installed, otherwise this will upgrade
chroot /root apt-get install dell-recovery -y --no-install-recommends

#only if we are in factory or bto-a
if chroot /root apt-cache show fist 2>/dev/null 1>/dev/null; then
    chroot /root apt-get install fist -y
fi

###Set up all preseeds###
# First test for and load override / configurations preseeds
# - needs to be loaded first so that we know if we are dual boot
for seed in dell-recovery gfx wlan; do
    if [ -e /root/cdrom/preseed/$seed.seed ]; then
        casper-set-selections /root/cdrom/preseed/$seed.seed
    fi
done

# Now load all the defaults included in all installs
casper-set-selections "/root/usr/share/dell/casper/seeds/ubuntu.seed"

# If we have a dual boot option, load the dual boot preseed
if db_get dell-recovery/dual_boot && [ "$RET" = true ]; then
    casper-set-selections "/root/usr/share/dell/casper/seeds/dual.seed"
fi

# Lastly, reload the override / configurations preseeds so that it is allowed to override stuff from ubuntu.seed and dual.seed
for seed in dell-recovery gfx wlan; do
    if [ -e /root/cdrom/preseed/$seed.seed ]; then
        casper-set-selections /root/cdrom/preseed/$seed.seed
    fi
done

# if no efibootmgr in livefs, force it.  needed for stage1
if [ -d /sys/firmware/efi ] && [ ! -x /root/bin/efibootmgr ]; then
    chroot /root apt-get install efibootmgr -y
fi

# disable snapd during installation to prevent OOM on small configurations
ln -s /dev/null /root/etc/systemd/system/snapd.service

# In case we're running a kernel not in the squashfs already
# we need to load modules into squashfs somehow
KERNELS=$(find /root/cdrom/kernel -maxdepth 1 -type d 2>/dev/null | sed "s,/root,,; /\/cdrom\/kernel\/$/d")
if [ -n "$KERNELS" ]; then
    for KERNEL in $KERNELS; do
        ln -s $KERNEL /root/lib/modules
    done
fi

# Clear out debconf database backup files to save memory.
rm -f /root/var/cache/debconf/*.dat-old

# Later emergency installer fixes
if [ -d /root/cdrom/scripts/emergency-scripts ]; then
    for script in /root/cdrom/scripts/emergency-scripts/[0-9]*; do
        . $script
    done
elif [ -d /root/isodevice/scripts/emergency-scripts ]; then
    for script in /root/isodevice/scripts/emergency-scripts/[0-9]*; do
        . $script
    done
fi

log_end_msg

exit 0

dell_bootstrap

#!/bin/sh -e
# initramfs hook for dell-bootstrap

PREREQS=""

# Output pre-requisites
prereqs()
{
       echo "$PREREQS"
}

case "$1" in
    prereqs)
       prereqs
       exit 0
       ;;
esac

. /usr/share/initramfs-tools/hook-functions

cp /usr/share/dell/scripts/pool.sh  $DESTDIR/scripts
if [ ! -f $DESTDIR/scripts/casper-bottom/99dell_bootstrap ]; then
    cp /usr/share/dell/casper/scripts/99dell_bootstrap $DESTDIR/scripts/casper-bottom
fi

#invoked from dell-recovery
if [ -n "$INJECT" ]; then
    if ! grep 99dell_bootstrap $DESTDIR/scripts/casper-bottom/ORDER >/dev/null; then
        cat >> $DESTDIR/scripts/casper-bottom/ORDER << EOF
/scripts/casper-bottom/99dell_bootstrap "\$@"
[ -e /conf/param.conf ] && . /conf/param.conf
EOF
    fi
fi

主要作的事儿

  1. 强制修改ubiquity运行在 AUTOMATIC 模式下。(包括桌面快捷方式)
  2. 配置源(见pool.sh)
  3. 安装dell-recovery
  4. 使用seed文件,预置debconf的值

pool.sh

#!/bin/sh
#
#       <pool.sh>
#
#       Builds a pool from important stuff in /cdrom
#       * Expects to be called as root w/ /cdrom referring to our stuff
#
#       Copyright 2010 Dell Inc.
#           Mario Limonciello <Mario_Limonciello@Dell.com>
#
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
# vim:ts=8:sw=8:et:tw=0

[ -d /cdrom/debs ] || [ -d /isodevice/debs ] || [ -d /dell/debs ]

#Persistent mode has a tendency to break the dynamic apt cache
if grep -q persistent /proc/cmdline 2>/dev/null; then
    rm -f /etc/apt/sources.list.d/dell.list
fi

#This allows things that aren't signed to be installed
if [ ! -f /etc/apt/apt.conf.d/00AllowUnauthenticated ]; then
    cat > /etc/apt/apt.conf.d/00AllowUnauthenticated << EOF
APT::Get::AllowUnauthenticated "true";
Aptitude::CmdLine::Ignore-Trust-Violations "true";
Acquire::AllowInsecureRepositories "true";
EOF
fi

#Prevents apt-get from complaining about unmounting and mounting the hard disk
if [ ! -f /etc/apt/apt.conf.d/00NoMountCDROM ]; then
    cat > /etc/apt/apt.conf.d/00NoMountCDROM << EOF
APT::CDROM::NoMount "true";
Acquire::cdrom 
{
    mount "/cdrom";
    "/cdrom/" 
    {
        Mount  "true";
        UMount "true";
    };
    AutoDetect "false";
};
EOF
fi

if [ ! -f /etc/apt/sources.list.d/dell.list ]; then
    #extra sources need to be disabled for this
    if find /etc/apt/sources.list.d/ -type f | grep sources.list.d; then
        mkdir -p /etc/apt/sources.list.d.old
        mv /etc/apt/sources.list.d/* /etc/apt/sources.list.d.old
    fi
    #Produce a dynamic list
    for dir in /cdrom/debs /isodevice/debs /dell/debs;
    do
        if [ -d "$dir" ]; then
            cd $dir
            apt-ftparchive packages ../../$dir | sed "s/^Filename:\ ..\//Filename:\ .\//" >> /Packages
        fi
    done
    if [ -f /Packages ]; then
        echo "deb file:/ /" > /etc/apt/sources.list.d/dell.list
    fi

    #add the static list to our file
    apt-cdrom -m add
    if grep "^deb cdrom" /etc/apt/sources.list >> /etc/apt/sources.list.d/dell.list; then
        sed -i "/^deb\ cdrom/d" /etc/apt/sources.list
    fi

    #fill up the cache
    mv /etc/apt/sources.list /etc/apt/sources.list.ubuntu
    touch /etc/apt/sources.list
    apt-get update

fi

if [ "$1" = "cleanup" ]; then
    #cleanup
    #if /etc/apt/sources.list has contained the regional mirror site, it is better to use it.
    if grep -v "^#" /etc/apt/sources.list | grep archive.ubuntu.com >/dev/null 2>&1; then
        rm -f /etc/apt/sources.list.ubuntu
        # Ensure Canonical's 'partner' repository enabled.
        sed -i 's/# deb \(.*\) partner$/deb \1 partner/g' /etc/apt/sources.list
    else
        mv /etc/apt/sources.list.ubuntu /etc/apt/sources.list
    fi
    rm -f /Packages /etc/apt/apt.conf.d/00AllowUnauthenticated /etc/apt/apt.conf.d/00NoMountCDROM
    rm -f /etc/apt/sources.list.d/dell.list
    if [ -d /etc/apt/sources.list.d.old ]; then
        mv /etc/apt/sources.list.d.old/* /etc/apt/sources.list.d
        rm -rf /etc/apt/sources.list.d.old
    fi
fi

live中的grub.cfg

来自:

shutil.copy('/usr/share/dell/grub/theme/grub.cfg',
                        os.path.join(tmpdir, 'boot', 'grub', 'grub.cfg'))

这个处理是在recovery_backend中。

其中 /usr/share/dell/grub/theme/grub.cfg内容:

#########################################################
#                                                       #
# Dell Grub2 configuration file for ISO Images          #
# By: Mario Limonciello <Mario_Limonciello@Dell.com>    #
#                                                       #
#########################################################

# First check for additional options on ISO image
if [ -s /factory/common.cfg ]; then
    source /factory/common.cfg
fi

#Post RTS deliverables
if [ -s /factory/post-rts-gfx.cfg ]; then
    source /factory/post-rts-gfx.cfg
fi
if [ -s /factory/post-rts-wlan.cfg ]; then
    source /factory/post-rts-wlan.cfg
fi

# If missing, load a nice basic default set
if [ -z "${options}" ]; then
    set options="boot=casper automatic-ubiquity noprompt quiet splash nomodeset nopersistent --"
fi

# Setup theme
set timeout=2
set gfxmode=auto
insmod gfxterm
terminal_output gfxterm
loadfont /boot/grub/dejavu-sans-12.pf2
loadfont /boot/grub/dejavu-sans-bold-14.pf2
insmod gfxmenu
insmod png
set theme=/boot/grub/dell/theme.txt

# Search for the RP (which contains grubenv in /factory)
search --file --set=new_root /factory/grubenv
if [ -s ($new_root)/factory/grubenv ]; then
    set have_grubenv=true
    load_env -f ($new_root)/factory/grubenv
    if [ "x${install_in_progress}" = "x1" ]; then
        set root=$new_root
        configfile ($new_root)/factory/grub.cfg
    else
        set timeout=-1
        menuentry "Install Complete, remove media and reboot." {
        chainloader +1
        }
    fi
fi

#allow OS to choose kernel extension if it wants
kernel=/casper/vmlinuz
if [ ! -f $kernel ]; then
  kernel=/casper/vmlinuz.efi
fi

#Default behavior
menuentry "Dell Recovery" {
    set gfxpayload=keep
    linux   $kernel $options
    initrd  /casper/initrd
}

live中factory中的grub.cfg来自

#Check for a grub.cfg - replace as necessary
        files = {'recovery_partition.cfg': 'grub.cfg',
                }
        for item in files:
            full_path = os.path.join('/mnt', 'factory', files[item])
            if os.path.exists(full_path):
                with misc.raised_privileges():
                    shutil.move(full_path, full_path + '.old')

            with misc.raised_privileges():
                magic.process_conf_file('/usr/share/dell/grub/' + item, \
                                        full_path, uuid, EFI_RP_PARTITION)

该处理在dell-recovery中(ubiquity的插件)
将 /usr/share/dell/grub/recovery_partition.cfg 处理过后(替换UUID等)放入 /mnt/factory/grub.cfg中

##set install_in_progress flag
        with misc.raised_privileges():
            if not os.path.exists('/mnt/factory/grub.cfg'):
                build = misc.execute_root('/usr/share/dell/grub/build-factory.sh')
                if build is False:
                    raise RuntimeError("Error building grub cfg.")
                with misc.raised_privileges():
                    magic.white_tree("copy", re.compile('.'), '/var/lib/dell-recovery', '/mnt/factory')
            magic.fetch_output(['grub-editenv', '/mnt/factory/grubenv', 'set', 'install_in_progress=1'])

这里感觉有点重复 不知道什么情况会导致 /mnt/factory/grub.cfg不存在。

magic.fetch_output(['grub-editenv', '/mnt/factory/grubenv', 'set', 'install_in_progress=1']这个标记在grub阶段很重要!!!!

#########################################################
#                                                       #
# Dell Grub2 configuration file for recovery partitions #
# By: Mario Limonciello <Mario_Limonciello@Dell.com>    #
#                                                       #
#########################################################

#
# Try to load the grub environment. We may have set a failure bit here.
#  If the failure bit is set, then we don't default to automatic install
#
if [ -s /factory/grubenv ]; then
  set have_grubenv=true
  load_env -f /factory/grubenv
fi
if [ "${recordfail}" = 1 ]; then
  set timeout=-1
  set default=0
else
  set timeout=0
  set default=7
fi

#
# Load other misc defaults
#

#First check our current directory for additional options
if [ -s /factory/common.cfg ]; then
    source /factory/common.cfg
fi

#Post RTS deliverables
if [ -s /factory/post-rts-gfx.cfg ]; then
    source /factory/post-rts-gfx.cfg
fi
if [ -s /factory/post-rts-wlan.cfg ]; then
    source /factory/post-rts-wlan.cfg
fi

#Now set the root partition that has our OS installer
search --no-floppy --hint '(hd0,#PARTITION#)' --set --fs-uuid #UUID#

#If we still don't have options, they are on the the RP too, look there
#If missing, load a nice basic default set
if [ -z "${options}" ]; then
    if [ -s /factory/common.cfg ]; then
        source /factory/common.cfg
    else
        set options="boot=casper automatic-ubiquity noprompt quiet splash nomodeset nopersistent --"
    fi
    #Post RTS deliverables
    if [ -s /factory/post-rts-gfx.cfg ]; then
        source /factory/post-rts-gfx.cfg
    fi
    if [ -s /factory/post-rts-wlan.cfg ]; then
        source /factory/post-rts-wlan.cfg
    fi
fi

set uuid_options="uuid=#UUID#"

#Support starting from a loopback mount (Only support ubuntu.iso for filename)
if [ -f /ubuntu.iso ]; then
    loopback loop /ubuntu.iso
    set root=(loop)
    set loop_options="iso-scan/filename=/ubuntu.iso"
fi

set menu_color_normal=white/red
set menu_color_highlight=red/white

#
# Show the menu if we press shift
#
if [ "x${timeout}" != "x-1" ]; then
  if keystatus; then
    if keystatus --shift; then
      set timeout=-1
    else
      set timeout=0
    fi
  else
    if sleep --interruptible 3 ; then
      set timeout=0
    fi
  fi
fi

#Set up for EFI if need be
if loadfont /boot/grub/font.pf2 ; then
    set gfxmode=auto
    insmod efi_gop
    insmod efi_uga
    insmod gfxterm
    terminal_output gfxterm
fi

kernel=/casper/vmlinuz
if [ ! -f $kernel ]; then
  kernel=/casper/vmlinuz.efi
fi
#We currently assume all machines can do this
#There is a blacklist system in ubuntu though
#that can be implemented if need be.
set gfxpayload=keep

#
# Debugging information and options
#
menuentry "If you are seeing this menu, your installation has failed." {
  chainloader +1
}
#
# Add collecting logs function for factory to provide more failed info to analysis issue
#
menuentry "To collect logs insert a USB recovery stick and select one of these options:" {
  chainloader +1
}

menuentry "    Collect OS installation logs" {
  search --file --set=new_root /efi/boot/grubx64.efi
  set root=$new_root
  linux $kernel $options
  initrd /casper/initrd
}
menuentry "    Collect OS installation logs (command line mode)" {
  search --file --set=new_root /efi/boot/grubx64.efi
  set root=$new_root
  linux $kernel boot=casper automatic-ubiquity noprompt quiet nomodeset nopersistent init=/bin/bash
  initrd /casper/initrd
}

menuentry "For interactive debugging select the following option:" {
  chainloader +1
}

menuentry "    Single User Mode" {
  linux $kernel boot=casper noprompt single nopersistent $uuid_options $loop_options --
  initrd /casper/initrd
}

#
# Default option
#
menuentry "To try install again select this option:" {
  chainloader +1
}
menuentry "    Automated Installation of #OS# (Default)" {
  set recordfail=1
  if [ -n "${have_grubenv}" ]; then save_env -f /factory/grubenv recordfail; fi
  linux $kernel $uuid_options $options $loop_options
  initrd /casper/initrd
}

关于EFI

#Install grub
        self.status("Installing GRUB", 88)
        ##If we don't have grub binaries, build them
        grub_files = ['bootx64.efi', 'grubx64.efi']

        ##Mount ESP
        mount = misc.execute_root('mount', self.device + esp_part, '/mnt/efi')
        if mount is False:
            raise RuntimeError("Error mounting %s%s" % (self.device, esp_part))

        direct_path = '/mnt/efi' + '/efi/ubuntu'
        with misc.raised_privileges():
            os.makedirs(direct_path)

            #copy boot loader files
            for root, dirs, files in os.walk('/cdrom', topdown=False):
                for bootloader in grub_files:
                    for f in files:
                        if bootloader in f.lower():
                            shutil.copy(os.path.join(root,f), direct_path)

            #find old entries
            bootmgr_output = magic.fetch_output(['efibootmgr', '-v']).split('\n')

            #delete old entries
            for line in bootmgr_output:
                bootnum = ''
                if line.startswith('Boot') and 'ubuntu' in line.lower():
                    bootnum = line.split('Boot')[1].replace('*', '').split()[0]
                if bootnum:
                    bootmgr = misc.execute_root('efibootmgr', '-v', '-b', bootnum, '-B')
                    if bootmgr is False:
                        raise RuntimeError("Error removing old EFI boot manager entries")

        target = 'shimx64.efi'
        with misc.raised_privileges():
            os.rename(os.path.join(direct_path, 'bootx64.efi'),
                      os.path.join(direct_path, target))

        add = misc.execute_root('efibootmgr', '-v', '-c', '-d', self.device, '-p', EFI_ESP_PARTITION, '-l', '\\EFI\\ubuntu\\%s' % target, '-L', 'ubuntu')
        if add is False:
            raise RuntimeError("Error adding efi entry to %s%s" % (self.device, esp_part))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容