Date: Sat, 5 Dec 2015 01:12:45 +0000 (UTC) From: Warner Losh <imp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r291831 - head/tools/tools/nanobsd Message-ID: <201512050112.tB51CjRE050428@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: imp Date: Sat Dec 5 01:12:44 2015 New Revision: 291831 URL: https://svnweb.freebsd.org/changeset/base/291831 Log: Awk helper script that reads in a mtree METALOG file from installworld (and soon augmented by nanobsd), performs the actions documented in the script, and then spits out a new mtree file suitable for feeding to makefs. Discussed on: arch@ Added: head/tools/tools/nanobsd/mtree-dedup.awk (contents, props changed) Added: head/tools/tools/nanobsd/mtree-dedup.awk ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/tools/nanobsd/mtree-dedup.awk Sat Dec 5 01:12:44 2015 (r291831) @@ -0,0 +1,197 @@ +#!/usr/bin/awk -f + +# +# Copyright (c) 2015 M. Warner Losh. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +# +# Takes a meta-log created by installworld and friends, plus +# additions from NanoBSD to augment its build to communicate when +# files move around after installworld / installkernel phase of +# NanoBSD. +# +# All mtree lines from the metafile have a path, followed by +# a number of keywords. +# +# This script recognizes the following new keywords +# +# unlink[=x] remove the path from the output. +# copy_from=x create new entry for path copied from +# the keywords from x. +# move_from=x create new entry for path copied from +# the keywords from x. Remove path from +# the output. +# +# In addition, when path matches a previous entry, the +# new entry and previous entry are merged. +# +# Special note: when uid and uname are both present, +# uid is ignored. Ditto gid/gname. +# +# Also, the paths above have to match exactly, so X +# should start with "./". +# + +function die(str) +{ + print str > "/dev/stderr"; + exit 1; +} + +function kv(str) +{ + if (split(str, xxx, "=") == 2) { + kv_key = xxx[1]; + kv_value = xxx[2]; + } else { + kv_key = str; + kv_value = nv; + } +} + +# Output the mtree for path based on the kvs. +function mtree_from_kvs(path, kvs) +{ + lv = path " "; + for (k in kvs) { + if (kvs[k] == nv) + lv = lv k " "; + else + lv = lv k "=" kvs[k] " "; + } + return lv; +} + +# Parse the mtree line into path + KVs. Use a sentinal value +# for a bare keyword, which is extremely unlikely to be used +# for real. +function line2kv(kvs, str) +{ + delete kvs; + + n = split(str, yyy, " "); + for (i = 2; i <= n; i++) { + s = yyy[i]; + if (split(s, xxx, "=") == 2) + kvs[xxx[1]] = xxx[2]; + else + kvs[s] = nv; + } +} + + +# old += new +function merge_kvs(old, new) +{ + for (k in new) { + # uname / uid -- last one wins. + if (k == "uid" && "uname" in old) + delete old["uname"] + if (k == "uname" && "uid" in old) + delete old["uid"]; + # gname / gid -- last one wins. + if (k == "gid" && "gname" in old) + delete old["gname"] + if (k == "gname" && "gid" in old) + delete old["gid"]; + # Otherwise newest value wins + old[k] = new[k]; + } +} + +# Process the line we've read in, per the comments below +function process_line(path, new) +{ + # Clear kvs + line2kv(new_kvs, new); + + if ("unlink" in new_kvs) { + # A file removed + # Sanity check to see if tree[path] exists? + # Makes sure when foo/bar/baz exists and foo/bar + # unlinked, baz is gone (for all baz). + if (path !~ "^\./") + die("bad path in : " new); + delete tree[path]; # unlink + return; + # } else if (new_kvs["append_from"]) { # not implemented + } else if ("copy_from" in new_kvs) { + # A file copied from another location, preserve its + # attribute for new file. + # Also merge any new attributes from this line. + from = new_kvs["copy_from"]; + if (from !~ "^\./") + die("bad path in : " new); + delete new_kvs["copy_from"]; + line2kv(old_kvs, tree[from]); # old_kvs = kv's in entry + merge_kvs(old_kvs, new_kvs); # old_kvs += new_kvs + tree[path] = mtree_from_kvs(path, old_kvs); + } else if ("move_from" in new_kvs) { + # A file moved from another location, preserve its + # attribute for new file, and scrag old location + # Also merge any new attributes from this line. + from = new_kvs["move_from"]; + if (from !~ "^\./") + die("bad path in : " new); + delete new_kvs["move_from"]; + line2kv(old_kvs, tree[from]); # old_kvs = kv's in entry + merge_kvs(old_kvs, new_kvs); # old_kvs += new_kvs + tree[path] = mtree_from_kvs(path, old_kvs); + delete tree[from]; # unlink + } else if (tree[path]) { # Update existing entry with new line + line2kv(old_kvs, tree[path]); # old_kvs = kv's in entry + merge_kvs(old_kvs, new_kvs); # old_kvs += new_kvs + tree[path] = mtree_from_kvs(path, old_kvs); + } else { # Add entry plus defaults + delete old_kvs; + merge_kvs(old_kvs, defaults); + merge_kvs(old_kvs, new_kvs); + tree[path] = mtree_from_kvs(path, old_kvs); + } +} + +BEGIN { + nv = "___NO__VALUE___"; + + while ((getline < "/dev/stdin") > 0) { + if ($1 == "/set") { + for (i = 2; i <= NF; i++) { + kv($i); + defaults[kv_key] = kv_value; + } + } else if ($1 == "/unset") { + for (i = 2; i <= NF; i++) { + kv($i); + delete defaults[kv_key]; + } + } else + process_line($1, $0); + } + + for (x in tree) + print tree[x]; +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512050112.tB51CjRE050428>