Haskus-Manual Release 0.1

Total Page:16

File Type:pdf, Size:1020Kb

Haskus-Manual Release 0.1 haskus-manual Release 0.1 Sylvain HENRY Aug 03, 2017 System - Volume 1: building guide 1 haskus-system 1 1.1 Introduction...............................................1 1.2 Discussing the approach.........................................2 1.3 Building systems: the automated way..................................5 1.4 Building systems: the manual way....................................7 1.5 Reference: system.yaml syntax................................... 11 1.6 Reference: haskus-system-build ................................. 13 1.7 The Sys monad.............................................. 13 1.8 Device management........................................... 14 1.9 Graphics Overview............................................ 19 1.10 Modules Overview............................................ 25 1.11 X86 architecture notes.......................................... 26 1.12 X86 encoding............................................... 27 2 haskus-binary 29 2.1 Binary modules.............................................. 29 3 haskus-utils 37 i ii CHAPTER 1 haskus-system haskus-system is a framework written in Haskell that can be used for system programming. Fundamentally it is an experiment into providing an integrated interface leveraging Haskell features (type-safety, STM, etc.) for the whole system: input, display, sound, network, etc. Introduction haskus-system is a framework written in Haskell that can be used for system programming. Fundamentally it is an experiment into providing an integrated interface leveraging Haskell features (type-safety, STM, etc.) for the whole system: input, display, sound, network, etc. The big picture A typical operating system can be roughly split into three layers: • Kernel: device drivers, virtual memory management, process scheduling, etc. • System: system services and daemons, low-level kernel interfaces, etc. • Application: end-user applications (web browser, video player, games, etc.) Linux kernel haskus-system is based directly and exclusively on the Linux kernel. Hence, • it doesn’t rely on usual user-space kernel interfaces (e.g., libdrm, libinput, X11, wayland, etc.) to communicate with the kernel • it doesn’t contain low-level kernel code (device driver, etc.) Note, however, that programs using the haskus-system are compiled with GHC: hence they still depend on GHC’s runtime system (RTS) dependencies (libc, etc.). Programs are statically compiled to embed those dependencies. haskus-system 1 haskus-manual, Release 0.1 haskus-system acts at the system level: it provides interfaces to the Linux kernel (hence to the hardware) in Haskell and builds on them to provide higher-level interfaces (described in the Volume 2 of this documentation). You can use these interfaces to build custom systems. Then it is up to you to decide if your system has the concept of “application” or not: you may design domain specific systems which provide a single “application”. Discussing the approach The haskus-system framework aims to help writing systems in Haskell. Writing a new operating system from scratch is obviously a huge task that we won’t undertake. Instead, pragmatically, we build on the Linux kernel to develop the haskus-system. The fact that it is based on the Linux kernel shouldn’t confuse you: we don’t have to let applications directly access it through a UNIX-like interface! This is similar to the approach followed by Google with Android: the Linux kernel is used internally but applications have to be written in Java and they have to use the Android interfaces. The difference is that we are using Haskell. The haskus-system framework and the systems using it are written with the Haskell language. We use GHC to compile Haskell codes, hence we rely on GHC’s runtime system. This runtime system works on a bare-bones Linux kernel and manages memory (garbage collection), user-space threading, asynchronous I/O, etc. Portability The portability is ensured by the Linux kernel. In theory we could use our approach on any architecture supported by the Linux kernel. In practice, we also need to ensure that GHC supports the target architecture. In addition, haskus-system requires a thin architecture-specific layer because Linux interface is architecture spe- cific. Differences between architectures include: system call numbers, some structure fields (sizes and orders), the instruction to call into a system call and the way to pass system call parameters (calling convention). The following architectures are currently supported by each level of the stack: • haskus-system: x86-64 • GHC: x86, x86-64, PowerPC, and ARM • Linux kernel: many architectures Performance Using a high-level language such as Haskell is a trade-off between performance and productivity. Just like using C lan- guage instead of plain assembly language is. Moreover in both cases we expect the compilers to perform optimizations that are not obvious or that would require complicated hard to maintain codes if they were to be coded explicitly. GHC is the Haskell compiler we use. It is a mature compiler still actively developed. It performs a lot of optimizations. In particular, it performs inter-modules optimizations so that well-organized modular code doesn’t endure performance costs. Haskell codes are compiled into native code for the architecture (i.e., there is no runtime interpretation of the code). In addition, it is possible to use LLVM as a GHC backend to generate the native code. The generated native codes are linked with a runtime system provided by GHC that manages: • Memory: garbage collection • Threading: fast and cheap user-space threading • Software transactional memory (STM): safe memory locking 2 Chapter 1. haskus-system haskus-manual, Release 0.1 • Asynchronous I/O: non-blocking I/O interacting with the threading system Performance-wise, this is a crucial part of the stack we use. It has been carefully optimized and it is tunable for specific needs. It is composed of about 40k lines of C code. As a last resort, it is still possible to call codes written in other languages from Haskell through the Foreign Function Interface (FFI) or by adding a Primary Operation (primop). haskus-system uses these mechanisms to interact with the Linux kernel. It seems to us that this approach is a good trade-off. As comparison points, most UNIX-like systems rely on unsafe interpreted shell scripts (init systems, etc.); Google’s Android (with Dalvik) used to perform runtime bytecode interpretation and then just-in-time compilation, currently (with ART) it still uses a garbage collector; Apple’s platforms rely on a garbage collection variant called “automatic reference counting” in Objective-C and in Swift languages (while it might be more efficient, it requires much more care from the programmers); JavaScript based applications and applets (unsafe language, VM, etc.) tend to generalize even on desktop. Productivity Writing system code in a high-level language such as Haskell should be much more productive than writing it in a low-level language like C. • Most of the boilerplate code (e.g., error management, logging) can be abstracted away. • Thanks to the type system, many errors are caught during the compilation, which is especially useful with system programming because programs are harder to debug using standard methods and tools. Moreover it makes codes much easier to maintain because the compiler checks many more things during refactoring. • High-level code is often dense and terse. Hence we can show full working code snippets in the documentation that you can quickly copy. Moreover, writing system code is much more fun and we can quickly get enjoyable results. Durability and Evolution Our approach should be both durable and evolutive. Durable because we only use mature technology: Linux and GHC developments both started in early 1990s and are still very active. The only new layer in the stack is the haskus-system framework. All of these are open-source free software, ensuring long-term access to the sources. The approach is evolutive: Haskell language is evolving in a controlled way with GHC’s extensions (and a potential future Haskell standard revision); GHC as a compiler and a runtime system is constantly improving and support for new architectures could be added; Linux support for new hardware and new architectures is constantly enhanced and specific developments could be done to add features useful for the haskus-system (or your own system on top of it). The haskus-system framework itself is highly evolutive. First it is new and not tied to any standard. Moreover code refactoring in Haskell is much easier than in low-level languages such as C (thanks to the strong typing), hence we can easily enhance the framework interfaces as user code can easily be adapted. Single Code Base & Integration In our opinion, a big advantage of our approach is to have an integrated framework whose source is in a single code base. It makes it much easier to evolve at a fast pace without having to maintain interface compatibility between its internal components. Moreover, refactoring is usually safe and relatively easy in Haskell, so we could later split it into several parts if needed. 1.2. Discussing the approach 3 haskus-manual, Release 0.1 As a comparison point, usual Linux distributions use several system services and core libraries, most of them in their own repository and independently developed: libc, dbus, udev, libdrm, libinput, Mesa/X11/Wayland, PulseAudio, etc. It is worth noting that the issue has been identified and that an effort has been recently made
Recommended publications
  • Flexible Lustre Management
    Flexible Lustre management Making less work for Admins ORNL is managed by UT-Battelle for the US Department of Energy How do we know Lustre condition today • Polling proc / sysfs files – The knocking on the door model – Parse stats, rpc info, etc for performance deviations. • Constant collection of debug logs – Heavy parsing for common problems. • The death of a node – Have to examine kdumps and /or lustre dump Origins of a new approach • Requirements for Linux kernel integration. – No more proc usage – Migration to sysfs and debugfs – Used to configure your file system. – Started in lustre 2.9 and still on going. • Two ways to configure your file system. – On MGS server run lctl conf_param … • Directly accessed proc seq_files. – On MSG server run lctl set_param –P • Originally used an upcall to lctl for configuration • Introduced in Lustre 2.4 but was broken until lustre 2.12 (LU-7004) – Configuring file system works transparently before and after sysfs migration. Changes introduced with sysfs / debugfs migration • sysfs has a one item per file rule. • Complex proc files moved to debugfs • Moving to debugfs introduced permission problems – Only debugging files should be their. – Both debugfs and procfs have scaling issues. • Moving to sysfs introduced the ability to send uevents – Item of most interest from LUG 2018 Linux Lustre client talk. – Both lctl conf_param and lctl set_param –P use this approach • lctl conf_param can set sysfs attributes without uevents. See class_modify_config() – We get life cycle events for free – udev is now involved. What do we get by using udev ? • Under the hood – uevents are collect by systemd and then processed by udev rules – /etc/udev/rules.d/99-lustre.rules – SUBSYSTEM=="lustre", ACTION=="change", ENV{PARAM}=="?*", RUN+="/usr/sbin/lctl set_param '$env{PARAM}=$env{SETTING}’” • You can create your own udev rule – http://reactivated.net/writing_udev_rules.html – /lib/udev/rules.d/* for examples – Add udev_log="debug” to /etc/udev.conf if you have problems • Using systemd for long task.
    [Show full text]
  • Troubleshooting Passwords
    Troubleshooting Passwords The following procedures may be used to troubleshoot password problems: • Performing Password Recovery with an Existing Administrator, page 1 • Performing Password Recovery with No Existing Administrator, page 1 • Performing Password Recovery for the Linux Grapevine User Account, page 2 Performing Password Recovery with an Existing Administrator To perform password recovery for a user (administrator, installer or observer) where there exists at least one controller administrator (ROLE_ADMIN) user account, take the following steps: 1 Contact the existing administrator to set up a temporary password for the user that requires password recovery. Note The administrator can set up a temporary password by deleting the user's account and then recreating it with the lost password. The user can then log back into the controller to regain access and change the password once again to whatever he or she desires. 2 The user then needs to log into the controller with the temporary password and change the password. Note Passwords are changed in the controller GUI using the Change Password window. For information about changing passwords, see Chapter 4, Managing Users and Roles in the Cisco Application Policy Infrastructure Controller Enterprise Module Configuration Guide. Performing Password Recovery with No Existing Administrator The following procedure describes how to perform password recovery where there exists only one controller administrator (ROLE_ADMIN) user account and this account cannot be successfully logged into. Cisco Application Policy Infrastructure Controller Enterprise Module Troubleshooting Guide, Release 1.3.x 1 Troubleshooting Passwords Performing Password Recovery for the Linux Grapevine User Account Note We recommend that you create at least two administrator accounts for your deployment.
    [Show full text]
  • Reducing Power Consumption in Mobile Devices by Using a Kernel
    IEEE TRANSACTIONS ON MOBILE COMPUTING, VOL. Z, NO. B, AUGUST 2017 1 Reducing Event Latency and Power Consumption in Mobile Devices by Using a Kernel-Level Display Server Stephen Marz, Member, IEEE and Brad Vander Zanden and Wei Gao, Member, IEEE E-mail: [email protected], [email protected], [email protected] Abstract—Mobile devices differ from desktop computers in that they have a limited power source, a battery, and they tend to spend more CPU time on the graphical user interface (GUI). These two facts force us to consider different software approaches in the mobile device kernel that can conserve battery life and reduce latency, which is the duration of time between the inception of an event and the reaction to the event. One area to consider is a software package called the display server. The display server is middleware that handles all GUI activities between an application and the operating system, such as event handling and drawing to the screen. In both desktop and mobile devices, the display server is located in the application layer. However, the kernel layer contains most of the information needed for handling events and drawing graphics, which forces the application-level display server to make a series of system calls in order to coordinate events and to draw graphics. These calls interrupt the CPU which can increase both latency and power consumption, and also require the kernel to maintain event queues that duplicate event queues in the display server. A further drawback of placing the display server in the application layer is that the display server contains most of the information required to efficiently schedule the application and this information is not communicated to existing kernels, meaning that GUI-oriented applications are scheduled less efficiently than they might be, which further increases power consumption.
    [Show full text]
  • Version 7.8-Systemd
    Linux From Scratch Version 7.8-systemd Created by Gerard Beekmans Edited by Douglas R. Reno Linux From Scratch: Version 7.8-systemd by Created by Gerard Beekmans and Edited by Douglas R. Reno Copyright © 1999-2015 Gerard Beekmans Copyright © 1999-2015, Gerard Beekmans All rights reserved. This book is licensed under a Creative Commons License. Computer instructions may be extracted from the book under the MIT License. Linux® is a registered trademark of Linus Torvalds. Linux From Scratch - Version 7.8-systemd Table of Contents Preface .......................................................................................................................................................................... vii i. Foreword ............................................................................................................................................................. vii ii. Audience ............................................................................................................................................................ vii iii. LFS Target Architectures ................................................................................................................................ viii iv. LFS and Standards ............................................................................................................................................ ix v. Rationale for Packages in the Book .................................................................................................................... x vi. Prerequisites
    [Show full text]
  • I.MX Linux® Reference Manual
    i.MX Linux® Reference Manual Document Number: IMXLXRM Rev. 1, 01/2017 i.MX Linux® Reference Manual, Rev. 1, 01/2017 2 NXP Semiconductors Contents Section number Title Page Chapter 1 About this Book 1.1 Audience....................................................................................................................................................................... 27 1.1.1 Conventions................................................................................................................................................... 27 1.1.2 Definitions, Acronyms, and Abbreviations....................................................................................................27 Chapter 2 Introduction 2.1 Overview.......................................................................................................................................................................31 2.1.1 Software Base................................................................................................................................................ 31 2.1.2 Features.......................................................................................................................................................... 31 Chapter 3 Machine-Specific Layer (MSL) 3.1 Introduction...................................................................................................................................................................37 3.2 Interrupts (Operation)..................................................................................................................................................
    [Show full text]
  • Networking with Wicked in SUSE® Linux Enterprise 12
    Networking with Wicked in SUSE® Linux Enterprise 12 Something Wicked This Way Comes Guide www.suse.com Solution Guide Server Server Solution Guide Networking with Wicked in SUSE Linux Enterprise 12 Wicked QuickStart Guide Abstract: Introduced with SUSE® Linux Enterprise 12, Wicked is the new network management tool for Linux, largely replacing the sysconfig package to manage the ever-more-complicated network configurations. Wicked provides network configuration as a service, enabling you to change your configuration dynamically. This paper covers the basics of Wicked with an emphasis on Recently, new technologies have accelerated the trend toward providing correlations between how things were done previ- complexity. Virtualization requires on-demand provisioning of ously and how they need to be done now. resources, including networks. Converged networks that mix data and storage traffic on a shared link require a tighter integra- Introduction tion between stacks that were previously mostly independent. When S.u.S.E.1 first introduced its Linux distribution, network- ing requirements were relatively simple and static. Over time Today, more than 20 years after the first SUSE distribution, net- networking evolved to become far more complex and dynamic. work configurations are very difficult to manage properly, let For example, automatic address configuration protocols such as alone easily (see Figure 1). DHCP or IPv6 auto-configuration entered the picture along with a plethora of new classes of network devices. Modern Network Landscape While this evolution was happening, the concepts behind man- aging a Linux system’s network configuration didn’t change much. The basic idea of storing a configuration in some files and applying it at system boot up using a collection of scripts and system programs was pretty much the same.
    [Show full text]
  • O'reilly Linux Kernel in a Nutshell.Pdf
    ,title.4229 Page i Friday, December 1, 2006 9:52 AM LINUX KERNEL IN A NUTSHELL ,title.4229 Page ii Friday, December 1, 2006 9:52 AM Other Linux resources from O’Reilly Related titles Building Embedded Linux Running Linux Systems Understanding Linux Linux Device Drivers Network Internals Linux in a Nutshell Understanding the Linux Linux Pocket Guide Kernel Linux Books linux.oreilly.com is a complete catalog of O’Reilly’s Resource Center books on Linux and Unix and related technologies, in- cluding sample chapters and code examples. Conferences O’Reilly brings diverse innovators together to nurture the ideas that spark revolutionary industries. We spe- cialize in documenting the latest tools and systems, translating the innovator’s knowledge into useful skills for those in the trenches. Visit conferences.oreilly.com for our upcoming events. Safari Bookshelf (safari.oreilly.com) is the premier on- line reference library for programmers and IT professionals. Conduct searches across more than 1,000 books. Subscribers can zero in on answers to time-critical questions in a matter of seconds. Read the books on your Bookshelf from cover to cover or sim- ply flip to the page you need. Try it today for free. ,title.4229 Page iii Friday, December 1, 2006 9:52 AM LINUX KERNEL IN A NUTSHELL Greg Kroah-Hartman Beijing • Cambridge • Farnham • Köln • Paris • Sebastopol • Taipei • Tokyo ,LKNSTOC.fm.8428 Page v Friday, December 1, 2006 9:55 AM Chapter 1 Table of Contents Preface . ix Part I. Building the Kernel 1. Introduction . 3 Using This Book 4 2. Requirements for Building and Using the Kernel .
    [Show full text]
  • Linux for Zseries: Device Drivers and Installation Commands (March 4, 2002) Summary of Changes
    Linux for zSeries Device Drivers and Installation Commands (March 4, 2002) Linux Kernel 2.4 LNUX-1103-07 Linux for zSeries Device Drivers and Installation Commands (March 4, 2002) Linux Kernel 2.4 LNUX-1103-07 Note Before using this document, be sure to read the information in “Notices” on page 207. Eighth Edition – (March 2002) This edition applies to the Linux for zSeries kernel 2.4 patch (made in September 2001) and to all subsequent releases and modifications until otherwise indicated in new editions. © Copyright International Business Machines Corporation 2000, 2002. All rights reserved. US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. Contents Summary of changes .........v Chapter 5. Linux for zSeries Console || Edition 8 changes.............v device drivers............27 Edition 7 changes.............v Console features .............28 Edition 6 changes ............vi Console kernel parameter syntax .......28 Edition 5 changes ............vi Console kernel examples ..........28 Edition 4 changes ............vi Usingtheconsole............28 Edition 3 changes ............vii Console – Use of VInput ..........30 Edition 2 changes ............vii Console limitations ............31 About this book ...........ix Chapter 6. Channel attached tape How this book is organized .........ix device driver ............33 Who should read this book .........ix Tapedriverfeatures...........33 Assumptions..............ix Tape character device front-end........34 Tape block
    [Show full text]
  • Xen and the Linux Console Or: Why Xencons={Tty,Ttys,Xvc} Will Go Away
    Xen and the linux console or: why xencons={tty,ttyS,xvc} will go away. by Gerd Hoffmann <[email protected]> So, what is the Linux console? Well, there isn't a simple answer to that question. Which is the reason for this paper in the first place. For most users it probably is the screen they are sitting in front of. Which is correct, but it also isn't the full story. Especially there are a bunch of CONFIG_*_CONSOLE kernel options referring to two different (but related) subsystems of the kernel. Introducing virtual terminals (CONFIG_VT) Well, every linux user knows them: Virtual terminals. Using Alt-Fx you can switch between different terminals. Each terminal has its own device, namely /dev/tty<nr>. Most Linux distributions have a getty ready for text login on /dev/tty{1-6} and the X-Server for the graphical login on /dev/tty7. /dev/tty0 is a special case: It referes to the terminal which is visible at the moment. The VT subsystem doesn't draw the characters itself though, it has hardware specific drivers for that. The most frequently used ones are: CONFIG_VGA_CONSOLE VGA text console driver, this one will drive your VGA card if you boot the machine in VGA text mode. CONFIG_FRAMEBUFFER_CONSOLE Provides text screens on top of a graphical display. The graphical display in turn is driven by yet another driver. On x86 this very often is vesafb. Other platforms have generic drivers too. There are also a bunch of drivers for specific hardware, such as rivafb for nvidia cards.
    [Show full text]
  • MC-1200 Series Linux Software User's Manual
    MC-1200 Series Linux Software User’s Manual Version 1.0, November 2020 www.moxa.com/product © 2020 Moxa Inc. All rights reserved. MC-1200 Series Linux Software User’s Manual The software described in this manual is furnished under a license agreement and may be used only in accordance with the terms of that agreement. Copyright Notice © 2020 Moxa Inc. All rights reserved. Trademarks The MOXA logo is a registered trademark of Moxa Inc. All other trademarks or registered marks in this manual belong to their respective manufacturers. Disclaimer Information in this document is subject to change without notice and does not represent a commitment on the part of Moxa. Moxa provides this document as is, without warranty of any kind, either expressed or implied, including, but not limited to, its particular purpose. Moxa reserves the right to make improvements and/or changes to this manual, or to the products and/or the programs described in this manual, at any time. Information provided in this manual is intended to be accurate and reliable. However, Moxa assumes no responsibility for its use, or for any infringements on the rights of third parties that may result from its use. This product might include unintentional technical or typographical errors. Changes are periodically made to the information herein to correct such errors, and these changes are incorporated into new editions of the publication. Technical Support Contact Information www.moxa.com/support Moxa Americas Moxa China (Shanghai office) Toll-free: 1-888-669-2872 Toll-free: 800-820-5036 Tel: +1-714-528-6777 Tel: +86-21-5258-9955 Fax: +1-714-528-6778 Fax: +86-21-5258-5505 Moxa Europe Moxa Asia-Pacific Tel: +49-89-3 70 03 99-0 Tel: +886-2-8919-1230 Fax: +49-89-3 70 03 99-99 Fax: +886-2-8919-1231 Moxa India Tel: +91-80-4172-9088 Fax: +91-80-4132-1045 Table of Contents 1.
    [Show full text]
  • Communicating Between the Kernel and User-Space in Linux Using Netlink Sockets
    SOFTWARE—PRACTICE AND EXPERIENCE Softw. Pract. Exper. 2010; 00:1–7 Prepared using speauth.cls [Version: 2002/09/23 v2.2] Communicating between the kernel and user-space in Linux using Netlink sockets Pablo Neira Ayuso∗,∗1, Rafael M. Gasca1 and Laurent Lefevre2 1 QUIVIR Research Group, Departament of Computer Languages and Systems, University of Seville, Spain. 2 RESO/LIP team, INRIA, University of Lyon, France. SUMMARY When developing Linux kernel features, it is a good practise to expose the necessary details to user-space to enable extensibility. This allows the development of new features and sophisticated configurations from user-space. Commonly, software developers have to face the task of looking for a good way to communicate between kernel and user-space in Linux. This tutorial introduces you to Netlink sockets, a flexible and extensible messaging system that provides communication between kernel and user-space. In this tutorial, we provide fundamental guidelines for practitioners who wish to develop Netlink-based interfaces. key words: kernel interfaces, netlink, linux 1. INTRODUCTION Portable open-source operating systems like Linux [1] provide a good environment to develop applications for the real-world since they can be used in very different platforms: from very small embedded devices, like smartphones and PDAs, to standalone computers and large scale clusters. Moreover, the availability of the source code also allows its study and modification, this renders Linux useful for both the industry and the academia. The core of Linux, like many modern operating systems, follows a monolithic † design for performance reasons. The main bricks that compose the operating system are implemented ∗Correspondence to: Pablo Neira Ayuso, ETS Ingenieria Informatica, Department of Computer Languages and Systems.
    [Show full text]
  • How to Manually Switch Graphics Cards Macbook Pro
    How To Manually Switch Graphics Cards Macbook Pro How to manually switch between dedicated and integrated graphics Is there a "hack" to switch between graphics processors on the Retina Display MacBook Pro makes it possible to easily switch between graphics cards manually on these. gpu-switch is an application that allows to switch between the graphic cards of dual-GPU Macbook Pro models. On these computers, the "automatic graphics switching" option is turned on by how to determine which graphics card is in use on a 15" or 17" MacBook Pro. MacBook Pro models that were affected by this problem would often have visual the picture above for a half a second while switching between graphics cards). capsule backup in this mode so have to keep manually backing up my data. When using a Mac that supports automatic graphics switching, the system will Two entries should appear under Video Card: "Intel HD Graphics 4000". Installing Arch Linux on a MacBook (Air/Pro) or an iMac is quite similar to installing it on any other computer. Boot installation medium and switch to a free tty. and work through until you get to Prepare Hard Drive and use the "Manually configure block devices. Different MacBook models have different graphic cards. How To Manually Switch Graphics Cards Macbook Pro Read/Download Several support threads discussing issue related to GPU switching. Some early Retina-equipped MacBook Pro users are seeing graphical issues in Safari. Earlier "Late 2008" and "Mid-2009" MacBook Pro models equipped with dual graphics A tool called gfxCardStatus allows to switch it manually: gfx.io/.
    [Show full text]