diff options
author | android-build-prod (mdb) <android-build-team-robot@google.com> | 2019-10-18 00:11:55 +0000 |
---|---|---|
committer | android-build-prod (mdb) <android-build-team-robot@google.com> | 2019-10-18 00:11:55 +0000 |
commit | 403b3b6699f8601f0ade24916a262d53ec63a460 (patch) | |
tree | 3ba0856fd908e190970739e703dc4e81ce972e2d | |
parent | 5f061bd8e585b607cc0358b7b7d82403eb1c9e7b (diff) | |
parent | 6809488b429a1285ef430b56760f50ec20bff92b (diff) | |
download | cuttlefish_common-sdk-release.tar.gz |
Snap for 5949240 from 6809488b429a1285ef430b56760f50ec20bff92b to sdk-releaseplatform-tools-29.0.6platform-tools-29.0.5sdk-release
Change-Id: I9a778344c3fee6b838c2a8d6cb445a539161f743
-rw-r--r-- | host/commands/assemble_cvd/Android.bp | 5 | ||||
-rw-r--r-- | host/commands/assemble_cvd/assemble_cvd.cc | 36 | ||||
-rw-r--r-- | host/commands/assemble_cvd/flags.cc | 12 | ||||
-rw-r--r-- | host/commands/assemble_cvd/flags.h | 4 | ||||
-rw-r--r-- | host/commands/assemble_cvd/super_image_mixer.cc | 256 | ||||
-rw-r--r-- | host/commands/assemble_cvd/super_image_mixer.h | 23 | ||||
-rw-r--r-- | host/commands/launch/launch_cvd.cc | 2 | ||||
-rw-r--r-- | host/libs/vm_manager/vm_manager.cpp | 24 | ||||
-rw-r--r-- | host/libs/vm_manager/vm_manager.h | 2 | ||||
-rwxr-xr-x | tools/flash-blk-dev.sh | 44 | ||||
-rwxr-xr-x | tools/network-setup.sh | 53 |
11 files changed, 409 insertions, 52 deletions
diff --git a/host/commands/assemble_cvd/Android.bp b/host/commands/assemble_cvd/Android.bp index 6c88f0c9..e2965264 100644 --- a/host/commands/assemble_cvd/Android.bp +++ b/host/commands/assemble_cvd/Android.bp @@ -35,7 +35,8 @@ cc_binary_host { "boot_image_unpacker.cc", "data_image.cc", "flags.cc", - "image_aggregator.cc" + "image_aggregator.cc", + "super_image_mixer.cc", ], header_libs: [ "cuttlefish_glog", @@ -50,6 +51,8 @@ cc_binary_host { "libbase", "libnl", "libprotobuf-cpp-full", + "libziparchive", + "libz", ], static_libs: [ "libcuttlefish_host_config", diff --git a/host/commands/assemble_cvd/assemble_cvd.cc b/host/commands/assemble_cvd/assemble_cvd.cc index 9efc0dda..6eab814b 100644 --- a/host/commands/assemble_cvd/assemble_cvd.cc +++ b/host/commands/assemble_cvd/assemble_cvd.cc @@ -17,8 +17,32 @@ #include <glog/logging.h> +#include "common/libs/fs/shared_buf.h" +#include "common/libs/fs/shared_fd.h" +#include "common/libs/strings/str_split.h" #include "host/commands/assemble_cvd/assembler_defs.h" #include "host/commands/assemble_cvd/flags.h" +#include "host/libs/config/fetcher_config.h" + +namespace { + +std::string kFetcherConfigFile = "fetcher_config.json"; + +cvd::FetcherConfig FindFetcherConfig(const std::vector<std::string>& files) { + cvd::FetcherConfig fetcher_config; + for (const auto& file : files) { + auto expected_pos = file.size() - kFetcherConfigFile.size(); + if (file.rfind(kFetcherConfigFile) == expected_pos) { + if (fetcher_config.LoadFromFile(file)) { + return fetcher_config; + } + LOG(ERROR) << "Could not load fetcher config file."; + } + } + return fetcher_config; +} + +} // namespace int main(int argc, char** argv) { ::android::base::InitLogging(argv, android::base::StderrLogger); @@ -36,7 +60,17 @@ int main(int argc, char** argv) { } } - auto config = InitFilesystemAndCreateConfig(&argc, &argv); + std::string input_files_str; + { + auto input_fd = cvd::SharedFD::Dup(0); + auto bytes_read = cvd::ReadAll(input_fd, &input_files_str); + if (bytes_read < 0) { + LOG(FATAL) << "Failed to read input files. Error was \"" << input_fd->StrError() << "\""; + } + } + std::vector<std::string> input_files = cvd::StrSplit(input_files_str, '\n'); + + auto config = InitFilesystemAndCreateConfig(&argc, &argv, FindFetcherConfig(input_files)); std::cout << GetConfigFilePath(*config) << "\n"; std::cout << std::flush; diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc index 53743583..c5a8c36c 100644 --- a/host/commands/assemble_cvd/flags.cc +++ b/host/commands/assemble_cvd/flags.cc @@ -14,6 +14,8 @@ #include "host/commands/assemble_cvd/data_image.h" #include "host/commands/assemble_cvd/image_aggregator.h" #include "host/commands/assemble_cvd/assembler_defs.h" +#include "host/commands/assemble_cvd/super_image_mixer.h" +#include "host/libs/config/fetcher_config.h" #include "host/libs/vm_manager/crosvm_manager.h" #include "host/libs/vm_manager/qemu_manager.h" #include "host/libs/vm_manager/vm_manager.h" @@ -733,7 +735,8 @@ void CreateCompositeDisk(const vsoc::CuttlefishConfig& config) { } // namespace -const vsoc::CuttlefishConfig* InitFilesystemAndCreateConfig(int* argc, char*** argv) { +const vsoc::CuttlefishConfig* InitFilesystemAndCreateConfig( + int* argc, char*** argv, cvd::FetcherConfig fetcher_config) { if (!ParseCommandLineFlags(argc, argv)) { LOG(ERROR) << "Failed to parse command arguments"; exit(AssemblerExitCodes::kArgumentParsingError); @@ -823,6 +826,13 @@ const vsoc::CuttlefishConfig* InitFilesystemAndCreateConfig(int* argc, char*** a CreateBlankImage(FLAGS_metadata_image, FLAGS_blank_metadata_image_mb, "none"); } + if (SuperImageNeedsRebuilding(fetcher_config, *config)) { + if (!RebuildSuperImage(fetcher_config, *config, FLAGS_super_image)) { + LOG(ERROR) << "Super image rebuilding requested but could not be completed."; + exit(cvd::kCuttlefishConfigurationInitError); + } + } + if (ShouldCreateCompositeDisk()) { CreateCompositeDisk(*config); } diff --git a/host/commands/assemble_cvd/flags.h b/host/commands/assemble_cvd/flags.h index e8c542ff..03733881 100644 --- a/host/commands/assemble_cvd/flags.h +++ b/host/commands/assemble_cvd/flags.h @@ -1,6 +1,8 @@ #pragma once #include "host/libs/config/cuttlefish_config.h" +#include "host/libs/config/fetcher_config.h" -const vsoc::CuttlefishConfig* InitFilesystemAndCreateConfig(int* argc, char*** argv); +const vsoc::CuttlefishConfig* InitFilesystemAndCreateConfig( + int* argc, char*** argv, cvd::FetcherConfig config); std::string GetConfigFilePath(const vsoc::CuttlefishConfig& config); diff --git a/host/commands/assemble_cvd/super_image_mixer.cc b/host/commands/assemble_cvd/super_image_mixer.cc new file mode 100644 index 00000000..061497fa --- /dev/null +++ b/host/commands/assemble_cvd/super_image_mixer.cc @@ -0,0 +1,256 @@ +// +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "super_image_mixer.h" + +#include <cstdio> +#include <functional> +#include <memory> + +#include <glog/logging.h> + +#include "ziparchive/zip_archive.h" +#include "ziparchive/zip_writer.h" + +#include "common/libs/utils/files.h" +#include "common/libs/utils/subprocess.h" +#include "host/libs/config/cuttlefish_config.h" +#include "host/libs/config/fetcher_config.h" + +namespace { + +using cvd::FileExists; +using vsoc::DefaultHostArtifactsPath; + +std::string TargetFilesZip(const cvd::FetcherConfig& fetcher_config, + cvd::FileSource source) { + for (const auto& file_iter : fetcher_config.get_cvd_files()) { + if (file_iter.second.source != source) { + continue; + } + std::string expected_substr = "target_files-" + file_iter.second.build_id + ".zip"; + auto expected_pos = file_iter.first.size() - expected_substr.size(); + if (file_iter.first.rfind(expected_substr) == expected_pos) { + return file_iter.first; + } + } + return ""; +} + +class ZipArchiveDeleter { +public: + void operator()(ZipArchive* archive) { + CloseArchive(archive); + } +}; + +using ManagedZipArchive = std::unique_ptr<ZipArchive, ZipArchiveDeleter>; + +class CFileCloser { +public: + void operator()(FILE* file) { + fclose(file); + } +}; + +using ManagedCFile = std::unique_ptr<FILE, CFileCloser>; + +ManagedZipArchive OpenZipArchive(const std::string& path) { + ZipArchive* ptr; + int status = OpenArchive(path.c_str(), &ptr); + if (status != 0) { + LOG(ERROR) << "Could not open archive \"" << path << "\": " << status; + return {}; + } + return ManagedZipArchive(ptr); +} + +ManagedCFile OpenFile(const std::string& path, const std::string& mode) { + FILE* ptr = fopen(path.c_str(), mode.c_str()); + if (ptr == nullptr) { + int error_num = errno; + LOG(ERROR) << "Could not open \"" << path << "\". Error was " + << strerror(error_num); + return {}; + } + return ManagedCFile(ptr); +} + +const std::string kMiscInfoPath = "META/misc_info.txt"; +const std::string kSystemPath = "IMAGES/system.img"; +const std::string kSystemExtPath = "IMAGES/system_ext.img"; + +bool CopyZipFileContents(const uint8_t* buf, size_t buf_size, void* cookie) { + ZipWriter* out_writer = (ZipWriter*) cookie; + int32_t status = out_writer->WriteBytes(buf, buf_size); + if (status != 0) { + LOG(ERROR) << "Could not write zip file contents, error code " << status; + return false; + } + return true; +} + +bool CombineTargetZipFiles(const std::string& default_target_zip, + const std::string& system_target_zip, + const std::string& output_path) { + auto default_target = OpenZipArchive(default_target_zip); + if (!default_target) { + LOG(ERROR) << "Could not open " << default_target_zip; + return false; + } + auto system_target = OpenZipArchive(system_target_zip); + if (!system_target) { + LOG(ERROR) << "Could not open " << system_target_zip; + return false; + } + auto out_file = OpenFile(output_path, "wb"); + if (!out_file) { + LOG(ERROR) << "Could not open " << output_path; + return false; + } + ZipWriter out_writer{out_file.get()}; + + ZipEntry entry; + if (FindEntry(system_target.get(), kSystemPath, &entry) != 0) { + LOG(ERROR) << "System target files zip does not have " << kSystemPath; + return false; + } + + if (FindEntry(default_target.get(), kMiscInfoPath, &entry) != 0) { + LOG(ERROR) << "Default target files zip does not have " << kMiscInfoPath; + return false; + } + out_writer.StartEntry(kMiscInfoPath, 0); + ProcessZipEntryContents( + default_target.get(), &entry, CopyZipFileContents, (void*) &out_writer); + out_writer.FinishEntry(); + + bool system_target_has_ext = + FindEntry(system_target.get(), kSystemExtPath, &entry) == 0; + + void* iteration_cookie; + std::string name; + + StartIteration(default_target.get(), &iteration_cookie, "IMAGES/", ".img"); + for (int status = 0; status != -1; status = Next(iteration_cookie, &entry, &name)) { + if (name == "") { + continue; + } + LOG(INFO) << "Name is \"" << name << "\""; + if (name == kSystemPath) { + continue; + } else if (system_target_has_ext && name == kSystemExtPath) { + continue; + } + LOG(INFO) << "Writing " << name; + out_writer.StartEntry(name, 0); + ProcessZipEntryContents( + default_target.get(), &entry, CopyZipFileContents, (void*) &out_writer); + out_writer.FinishEntry(); + } + EndIteration(iteration_cookie); + + StartIteration(system_target.get(), &iteration_cookie, "IMAGES/", ".img"); + for (int status = 0; status != -1; status = Next(iteration_cookie, &entry, &name)) { + bool is_system_image = name == kSystemPath; + bool is_system_ext_image = name == kSystemExtPath; + if (!is_system_image && !is_system_ext_image) { + continue; + } + LOG(INFO) << "Writing " << name; + out_writer.StartEntry(name, 0); + ProcessZipEntryContents( + system_target.get(), &entry, CopyZipFileContents, (void*) &out_writer); + out_writer.FinishEntry(); + } + EndIteration(iteration_cookie); + + int success = out_writer.Finish(); + if (success != 0) { + LOG(ERROR) << "Unable to write combined image zip archive: " << success; + return false; + } + + return true; +} + +bool BuildSuperImage(const std::string& combined_target_zip, + const std::string& output_path) { + std::string build_super_image_binary; + std::string otatools_path; + if (FileExists(DefaultHostArtifactsPath("otatools/bin/build_super_image"))) { + build_super_image_binary = + DefaultHostArtifactsPath("otatools/bin/build_super_image"); + otatools_path = DefaultHostArtifactsPath("otatools"); + } else if (FileExists(DefaultHostArtifactsPath("bin/build_super_image"))) { + build_super_image_binary = + DefaultHostArtifactsPath("bin/build_super_image"); + otatools_path = DefaultHostArtifactsPath(""); + } else { + LOG(ERROR) << "Could not find otatools"; + return false; + } + return cvd::execute({ + build_super_image_binary, + "--path=" + otatools_path, + combined_target_zip, + output_path, + }) == 0; +} + +} // namespace + +bool SuperImageNeedsRebuilding(const cvd::FetcherConfig& fetcher_config, + const vsoc::CuttlefishConfig&) { + bool has_default_build = false; + bool has_system_build = false; + for (const auto& file_iter : fetcher_config.get_cvd_files()) { + if (file_iter.second.source == cvd::FileSource::DEFAULT_BUILD) { + has_default_build = true; + } else if (file_iter.second.source == cvd::FileSource::SYSTEM_BUILD) { + has_system_build = true; + } + } + return has_default_build && has_system_build; +} + +bool RebuildSuperImage(const cvd::FetcherConfig& fetcher_config, + const vsoc::CuttlefishConfig& config, + const std::string& output_path) { + std::string default_target_zip = + TargetFilesZip(fetcher_config, cvd::FileSource::DEFAULT_BUILD); + if (default_target_zip == "") { + LOG(ERROR) << "Unable to find default target zip file."; + return false; + } + std::string system_target_zip = + TargetFilesZip(fetcher_config, cvd::FileSource::SYSTEM_BUILD); + if (system_target_zip == "") { + LOG(ERROR) << "Unable to find system target zip file."; + return false; + } + std::string combined_target_zip = config.PerInstancePath("target_combined.zip"); + // TODO(schuffelen): Use otatools/bin/merge_target_files + if (!CombineTargetZipFiles(default_target_zip, system_target_zip, + combined_target_zip)) { + LOG(ERROR) << "Could not combine target zip files."; + return false; + } + bool success = BuildSuperImage(combined_target_zip, output_path); + if (!success) { + LOG(ERROR) << "Could not write the final output super image."; + } + return success; +} diff --git a/host/commands/assemble_cvd/super_image_mixer.h b/host/commands/assemble_cvd/super_image_mixer.h new file mode 100644 index 00000000..1b8c4201 --- /dev/null +++ b/host/commands/assemble_cvd/super_image_mixer.h @@ -0,0 +1,23 @@ +// +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "host/libs/config/cuttlefish_config.h" +#include "host/libs/config/fetcher_config.h" + +bool SuperImageNeedsRebuilding(const cvd::FetcherConfig& fetcher_config, + const vsoc::CuttlefishConfig& config); +bool RebuildSuperImage(const cvd::FetcherConfig& fetcher_config, + const vsoc::CuttlefishConfig& config, + const std::string& output_path); diff --git a/host/commands/launch/launch_cvd.cc b/host/commands/launch/launch_cvd.cc index 01d6799d..9d3b108a 100644 --- a/host/commands/launch/launch_cvd.cc +++ b/host/commands/launch/launch_cvd.cc @@ -37,7 +37,7 @@ * Controllable with a flag for extraordinary scenarios such as running from a * daemon which closes its own stdin. */ -DEFINE_bool(run_file_discovery, (bool) isatty(0), +DEFINE_bool(run_file_discovery, true, "Whether to run file discovery or get input files from stdin."); namespace { diff --git a/host/libs/vm_manager/vm_manager.cpp b/host/libs/vm_manager/vm_manager.cpp index d613a56c..ac5531a4 100644 --- a/host/libs/vm_manager/vm_manager.cpp +++ b/host/libs/vm_manager/vm_manager.cpp @@ -19,6 +19,7 @@ #include <memory> #include <glog/logging.h> +#include <sys/utsname.h> #include "common/libs/utils/users.h" #include "host/libs/config/cuttlefish_config.h" @@ -126,12 +127,31 @@ bool VmManager::UserInGroup(const std::string& group, return true; } +bool VmManager::LinuxVersionAtLeast4_8(std::vector<std::string>* config_commands) { + struct utsname info; + if (!uname(&info)) { + char* digit = strtok(info.release, "+.-"); + int major = atoi(digit); + if (digit) { + digit = strtok(NULL, "+.-"); + int minor = atoi(digit); + if (major > 4 || (major == 4 && minor >= 8)) { + return true; + } + } + } + LOG(ERROR) << "Kernel version must be >=4.8"; + config_commands->push_back("# Please upgrade your kernel to >=4.8"); + return false; +} + bool VmManager::ValidateHostConfiguration( std::vector<std::string>* config_commands) const { // the check for cvdnetwork needs to happen even if the user is not in kvm, so - // we cant just say UserInGroup("kvm") && UserInGroup("cvdnetwork") + // we can't just say UserInGroup("kvm") && UserInGroup("cvdnetwork") auto in_kvm = VmManager::UserInGroup("kvm", config_commands); auto in_cvdnetwork = VmManager::UserInGroup("cvdnetwork", config_commands); - return in_kvm && in_cvdnetwork; + auto linux_ver_4_8 = VmManager::LinuxVersionAtLeast4_8(config_commands); + return in_kvm && in_cvdnetwork && linux_ver_4_8; } } // namespace vm_manager diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h index 79d5bbdd..62adbf8c 100644 --- a/host/libs/vm_manager/vm_manager.h +++ b/host/libs/vm_manager/vm_manager.h @@ -54,6 +54,8 @@ class VmManager { protected: static bool UserInGroup(const std::string& group, std::vector<std::string>* config_commands); + static bool LinuxVersionAtLeast4_8(std::vector<std::string>* config_commands); + const vsoc::CuttlefishConfig* config_; VmManager(const vsoc::CuttlefishConfig* config); diff --git a/tools/flash-blk-dev.sh b/tools/flash-blk-dev.sh index 5b39381a..e5381e04 100755 --- a/tools/flash-blk-dev.sh +++ b/tools/flash-blk-dev.sh @@ -14,20 +14,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -source "${ANDROID_BUILD_TOP}/external/shflags/src/shflags" - -DEFINE_boolean expand \ - false "expand filesystem to fill device" "e" - -FLAGS_HELP="USAGE: $0 [flags] image" +usage() { + echo "USAGE: $0 [flags] image" + echo "flags:" + echo " -e,--expand: expand filesystem to fill device (default: false)" + echo " -h,--help: show this help (default: false)" +} -main () +main() { - image=$1 - if [ "${image}" == "" ]; then - flags_help - exit 1 - fi if [ ! -e "${image}" ]; then echo "error: can't find image. aborting..." exit 1 @@ -91,8 +86,12 @@ main () else dd if=${image} of=/dev/${blk_dev} bs=1M conv=sync,noerror status=progress fi + if [ $? != 0 ]; then + echo "error: failed to write to device. aborting..." + exit 1 + fi - if [ ${FLAGS_expand} -eq ${FLAGS_TRUE} ]; then + if [ ${expand} -eq 1 ]; then echo "Expanding partition and filesystem..." part_type=`sudo gdisk -l /dev/${blk_dev} 2>/dev/null | grep ": present" | sed 's/ *\([^:]*\):.*/\1/'` if [ "$part_type" == "MBR" ]; then @@ -112,6 +111,21 @@ main () sudo eject /dev/${blk_dev} } -FLAGS "$@" || exit $? -eval set -- "${FLAGS_ARGV}" +expand=0 +if [ "$1" == "-e" ] || [ "$1" == "--expand" ]; then + expand=1 + shift +fi + +if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + usage + exit 0 +fi + +image=$1 +if [ "${image}" == "" ]; then + usage + exit 1 +fi + main "$@" diff --git a/tools/network-setup.sh b/tools/network-setup.sh index 0556b6e5..2913c0df 100755 --- a/tools/network-setup.sh +++ b/tools/network-setup.sh @@ -19,67 +19,61 @@ if [[ "$OSTYPE" != "linux-gnu" ]]; then exit 1 fi +sleep_time=0.1 DEFAULTNET=$1 if [ "$DEFAULTNET" == "" ]; then - warn1=0 - warn2=0 - attempts=0 - sleep_time=0.1 - warn_after=2.0 - max_attempts=`echo "(${warn_after}/${sleep_time})-1" | bc` + warn_no_default_network=0 + warn_multiple_networks=0 + warn_disconnect_rockpi=0 while true; do DEFAULTNET=`ip link | grep "state UP" | sed 's/[0-9]*: \([^:]*\):.*/\1/'` if [[ "${DEFAULTNET}" == "" ]]; then - if [[ $warn1 -eq 0 ]]; then + if [[ $warn_no_default_network -eq 0 ]]; then echo "error: couldn't detect any connected default network" - warn1=1 - warn2=0 + warn_no_default_network=1 + warn_multiple_networks=0 fi continue elif [ `echo "$DEFAULTNET" | wc -l` -eq 1 ]; then break elif [ `echo "$DEFAULTNET" | wc -l` -ne 1 ]; then - if [[ $attempts -eq 0 ]]; then + if [[ $warn_disconnect_rockpi -eq 0 ]]; then echo "Please disconnect the network cable from the Rock Pi" + warn_disconnect_rockpi=1 fi - if [[ $warn2 -eq 0 ]] && [[ $attempts -ge $max_attempts ]]; then + if [[ $warn_multiple_networks -eq 0 ]]; then echo "error: detected multiple connected networks, not sure which to use as default:" for net in $DEFAULTNET; do echo " $net"; done - warn1=0 - warn2=1 + warn_no_default_network=0 + warn_multiple_networks=1 fi sleep $sleep_time - attempts=$((attempts+1)) fi done - echo "Found default network at ${DEFAULTNET}" - echo "Attach network cable from Rock Pi to PC's spare network port" fi # escalate to superuser if [ "$UID" -ne 0 ]; then - exec sudo bash "$0" "${CORPNET}" + exec sudo bash "$0" "${DEFAULTNET}" fi -warn3=0 -attempts=0 +echo "Found default network at ${DEFAULTNET}" +echo "Please reconnect network cable from Rock Pi to PC's spare network port" + +ROCKNETinit=`ip link | grep "state UP" | grep -v $DEFAULTNET | sed 's/[0-9]*: \([^:]*\):.*/\1/' | awk 'NF'` while true; do ROCKNET=`ip link | grep "state UP" | grep -v $DEFAULTNET | sed 's/[0-9]*: \([^:]*\):.*/\1/' | awk 'NF'` + networks=`echo "$ROCKNET" | wc -l` if [[ "${ROCKNET}" == "" ]]; then continue - elif [ `echo "$ROCKNET" | wc -l` -eq 1 ]; then + elif [ $networks -eq 1 ]; then break - elif [ `echo "$ROCKNET" | wc -l` -gt 1 ]; then - if [[ $attempts -eq 0 ]]; then - echo "Please keep the default network and rock pi network connected; disconnect the rest" - fi - if [[ $warn3 -eq 0 ]]; then - echo "error: detected multiple additional networks, not sure which is the Rock Pi:" - for net in $ROCKNET; do echo " $net"; done - warn3=1 + elif [ $networks -gt 1 ]; then + ROCKNET=`comm -3 <(echo "$ROCKNETinit" | sort) <(echo "$ROCKNET" | sort) | awk '{$1=$1};1'` + if [ "${ROCKNET}" != "" ]; then + break fi sleep $sleep_time - attempts=$((attempts+1)) fi done echo "Found Rock Pi network at ${ROCKNET}" @@ -129,7 +123,6 @@ cat /etc/default/dnsmasq | grep "ENABLED" >/dev/null if [ $? == 0 ]; then sed -i 's/.*ENABLED.*/ENABLED=1/' /etc/default/dnsmasq else - sed -i 's/.*ENABLED.*/ENABLED=1/' /etc/default/dnsmasq echo "ENABLED=1" >> /etc/default/dnsmasq fi |