stateless linux設定指令碼註解

來源:互聯網
上載者:User

stateless linux是fedora
core的一個項目,顧名思義,就是系統運行時不儲存持久狀態資訊,簡單來說就是不讓系統對持久存放裝置(比如硬碟)進行寫操作。一般用於
readonly root技術。在我最近的程式中,用stateless linux來達到多個虛擬機器共用同一份磁碟image。

stateless linux的設定檔案是/etc/sysconfig/readonly-root,/etc/rc.sysinit在系統啟動時讀取這個檔案,並根據檔案中的設定進行配置。

從/etc/rc.sysinit中摘取出來的關於readonly-root的設定代碼,在代碼中添加了注釋:
READONLY=
if [ -f /etc/sysconfig/readonly-root ]; then
    . /etc/sysconfig/readonly-root
fi

#/etc/sysconfig/readonly-root設定READONLY,TEMPORARY_STATE,RW_MOUNT,RW_LABEL,STATE_LABEL,STATE_MOUNT幾個變數。

#在readonly-root檔案中對這幾個變數的作用做了詳細的注釋。從下面的代碼中也可以體現出來。

if strstr "$cmdline" readonlyroot ; then
    READONLY=yes
    [ -z "$RW_MOUNT" ] && RW_MOUNT=/var/lib/stateless/writable
fi

#cmdline變數就是啟動時傳遞給kernel的參數,可以從/proc/cmdline中看到,例如:ro root=LABEL=/

if strstr "$cmdline" noreadonlyroot ; then
    READONLY=no
fi

# READONLY和TEMPORARY_STATE只要設定其中一個為yes就可以。

if [ "$READONLY" = "yes" -o "$TEMPORARY_STATE" = "yes" ]; then

#mount_empty函數的作用就是把參數$1指定的檔案或目錄複寫到$RW_MOUNT目錄下作為備份,然後把備份檔案使用bind方式mount到原來的檔案上。

#這樣原來的檔案仍然可見可讀,而且保證了唯讀,因為所有的寫操作都會作用在備份檔案上。cpio的-p參數指定了目標檔案夾是$RW_MOUNT,-d參數

#表示如果$1是多級目錄表示的一個檔案,則這個目錄結構會自動在$RW_MOUNT下原樣建立。如果$1是一個目錄,則目錄下的檔案不會被複製,這應該

#是mount_empty中的empty的意思。


    mount_empty() {
        if [ -e "$1" ]; then
            echo "$1" | cpio -p -vd "$RW_MOUNT" &>/dev/null
            mount -n --bind "$RW_MOUNT$1" "$1"
        fi
    }

#如果$1是一個目錄,則mount_dirs把$1下層的目錄結構按照原樣在$RW_MOUNT下建立。

    mount_dirs() {
        if [ -e "$1" ]; then
            mkdir -p "$RW_MOUNT$1"
            # fixme: find is bad
            find "$1" -type d -print0 | cpio -p -0vd "$RW_MOUNT" &>/dev/null
            mount -n --bind "$RW_MOUNT$1" "$1"
        fi
    }

    mount_files() {
        if [ -e "$1" ]; then
            cp -a --parents "$1" "$RW_MOUNT"
            mount -n --bind "$RW_MOUNT$1" "$1"
        fi
    }

#簡而言之,mount_{empty,dirs,files}都是針對參數$1而言,mount_empty只管$1,不管$1下面的任何結點,mount_dirs只管維持$1下層的目錄結構,

#mount_files維持$1下面的所有目錄和檔案。

    # Common mount options for scratch space regardless of
    # type of backing store
    mountopts=

#blkid命令用來索引或查看block裝置的屬性。-t參數用來指定一個屬性(屬性以name=value的方式表示,例如LABEL=/),-l參數表示

#搜尋其屬性值和-t參數指定的屬性值符合的block裝置。-o指定輸出格式,可選的有full, value, device。以下是輸出樣本。

#[root@jcwkyl etc]# blkid -t LABEL=/ -l -o full

#/dev/sda3: LABEL="/" UUID="8844f9c3-2836-4f29-aaab-3fb6b6d0a1bf" SEC_TYPE="ext2" TYPE="ext3"

#[root@jcwkyl etc]# blkid -t LABEL=/ -l -o value

#/

#8844f9c3-2836-4f29-aaab-3fb6b6d0a1bf

#ext2

#ext3

#[root@jcwkyl etc]# blkid -t LABEL=/ -l -o device

#/dev/sda3

    # Scan partitions for local scratch storage
    rw_mount_dev=$(blkid -t LABEL="$RW_LABEL" -l -o device)

#這段代碼中的注釋說的非常清楚了,首先嘗試從/etc/fstab中的設定來mount,如果/etc/fstab中沒有設定,

#則直接把上一步找到的分區mount到$RW_MOUNT,如果還沒有成功,則把$RW_MOUNT目錄mount成tmpfs

    # First try to mount scratch storage from /etc/fstab, then any
    # partition with the proper label.  If either succeeds, be sure
    # to wipe the scratch storage clean.  If both fail, then mount
    # scratch storage via tmpfs.
    if mount $mountopts "$RW_MOUNT" > /dev/null 2>&1 ; then
        rm -rf "$RW_MOUNT" > /dev/null 2>&1
   
elif [ x$rw_mount_dev != x ] && mount $rw_mount_dev $mountopts
"$RW_MOUNT" > /dev/null 2>&1; then
        rm -rf "$RW_MOUNT"  > /dev/null 2>&1
    else
        mount -n -t tmpfs $mountopts none "$RW_MOUNT"
    fi

    for file in /etc/rwtab /etc/rwtab.d/* ; do
        is_ignored_file "$file" && continue
            [ -f $file ] && cat $file | while read type path ; do
            case "$type" in
                empty)
                    mount_empty $path
                    ;;
                files)
                    mount_files $path
                    ;;
                dirs)
                    mount_dirs $path
                    ;;
                *)
                    ;;
            esac
            [ -n "$SELINUX_STATE" -a -e "$path" ] && restorecon -R "$path"
        done
    done

    # In theory there should be no more than one network interface active
    # this early in the boot process -- the one we're booting from.
    # Use the network address to set the hostname of the client.  This
    # must be done even if we have local storage.
    ipaddr=
    if [ "$HOSTNAME" = "localhost" -o "$HOSTNAME" = "localhost.localdomain" ]; then
   
    ipaddr=$(ip addr show to 0/0 scope global | awk
'/[[:space:]]inet / { print gensub("/.*","","g",$2) }')
        if [ -n "$ipaddr" ]; then
            eval $(ipcalc -h $ipaddr 2>/dev/null)
            hostname ${HOSTNAME}
        fi
    fi
   
    # Clients with read-only root filesystems may be provided with a
    # place where they can place minimal amounts of persistent
    # state.  SSH keys or puppet certificates for example.
    #
    # Ideally we'll use puppet to manage the state directory and to
    # create the bind mounts.  However, until that's all ready this
    # is sufficient to build a working system.

    # First try to mount persistent data from /etc/fstab, then any
    # partition with the proper label, then fallback to NFS
    state_mount_dev=$(blkid -t LABEL="$STATE_LABEL" -l -o device)
    if mount $mountopts $STATE_OPTIONS "$STATE_MOUNT" > /dev/null 2>&1 ; then
        /bin/true
   
elif [ x$state_mount_dev != x ] && mount $state_mount_dev
$mountopts "$STATE_MOUNT" > /dev/null 2>&1;  then
        /bin/true
    elif [ ! -z "$CLIENTSTATE" ]; then
        # No local storage was found.  Make a final attempt to find
        # state on an NFS server.

        mount -t nfs $CLIENTSTATE/$HOSTNAME $STATE_MOUNT -o rw,nolock
    fi

    if [ -d $STATE_MOUNT/etc ]; then
        # Copy the puppet CA's cert from the r/o image into the
        # state directory so that we can create a bind mount on
        # the ssl directory for storing the client cert.  I'd really
        # rather have a unionfs to deal with this stuff
        cp --parents -f -p /var/lib/puppet/ssl/certs/ca.pem $STATE_MOUNT 2>/dev/null

        # In the future this will be handled by puppet
        for i in $(grep -v "^#" $STATE_MOUNT/files); do
            if [ -e $i ]; then
                 mount -n -o bind $STATE_MOUNT/${i} ${i}
            fi
         done
    fi
fi

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.