All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] Remove hypercall device
@ 2008-07-17 20:28 Anthony Liguori
  2008-07-17 20:28 ` [PATCH 2/5] Remove duplicate monitor definition Anthony Liguori
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Anthony Liguori @ 2008-07-17 20:28 UTC (permalink / raw)
  To: kvm; +Cc: Avi Kivity, Anthony Liguori

Removes hypercall device, old balloon device, and vmchannel stuff from QEMU.  The
stuff never was used publicly and is being/has been replaced by virtio.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu/Makefile.target b/qemu/Makefile.target
index 8ba8f9a..a7468c1 100644
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -575,9 +575,6 @@ OBJS += pcnet.o
 OBJS += rtl8139.o
 OBJS += e1000.o
 
-# PCI Hypercall
-OBJS+= hypercall.o
-
 # virtio devices
 OBJS += virtio.o virtio-net.o virtio-blk.o
 
diff --git a/qemu/hw/hypercall.c b/qemu/hw/hypercall.c
deleted file mode 100644
index 73f6bb1..0000000
--- a/qemu/hw/hypercall.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * QEMU-KVM Hypercall emulation
- * 
- * Copyright (c) 2003-2004 Fabrice Bellard
- * Copyright (c) 2006 Qumranet
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw/hw.h"
-#include "sysemu.h"
-#include "qemu-char.h"
-#include "hw/isa.h"
-#include "hw/irq.h"
-#include "hw/pci.h"
-#include "hypercall.h"
-#include <stddef.h>
-
-#define HYPERCALL_IOPORT_SIZE 0x100
-
-static int use_hypercall_dev = 0;
-
-typedef struct VmChannelCharDriverState {
-    CharDriverState *vmchannel_hd;
-    uint32_t deviceid;
-} VmChannelCharDriverState;
-
-static VmChannelCharDriverState vmchannel_hds[MAX_VMCHANNEL_DEVICES];
-
-typedef struct HypercallState {
-    uint32_t hcr;
-    uint32_t hsr;
-    uint32_t txsize;
-    uint32_t txbuff;
-    uint32_t rxsize;
-    uint8_t  RxBuff[HP_MEM_SIZE];
-    uint8_t  txbufferaccu[HP_MEM_SIZE];
-    int      txbufferaccu_offset;
-    int      irq;
-    PCIDevice *pci_dev;
-    uint32_t index;
-} HypercallState;
-
-static HypercallState *pHypercallStates[MAX_VMCHANNEL_DEVICES] = {NULL};
-
-//#define HYPERCALL_DEBUG 1
-
-static void hp_reset(HypercallState *s)
-{
-    s->hcr = HCR_DI;
-    s->hsr = 0;
-    s->txsize = 0;
-    s->txbuff = 0;
-    s->rxsize= 0;
-    s->txbufferaccu_offset = 0;
-}
-
-static void hypercall_update_irq(HypercallState *s);
-
-
-static void hp_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    HypercallState *s = opaque;
-
-#ifdef HYPERCALL_DEBUG
-    printf("%s: addr=0x%x, val=0x%x\n", __FUNCTION__, addr, val);
-#endif
-    addr &= 0xff;
-
-    switch(addr)
-    {
-        case HCR_REGISTER:
-        {
-            s->hcr = val;
-	    if (s->hcr & HCR_DI)
-                hypercall_update_irq(s);
-            if (val & HCR_GRS){
-                hp_reset(s);
-            }
-            break;
-        }
-
-        case HP_TXSIZE:
-        {
-            // handle the case when the we are being called when txsize is not 0
-            if (s->txsize != 0) {
-                printf("txsize is being set, but txsize is not 0!!!\n");
-            }
-            if (val > HP_MEM_SIZE) {
-                printf("txsize is larger than allowed by hw!!!\n");
-            }
-            s->txsize = val;
-            s->txbufferaccu_offset = 0;
-            break;
-        }
-
-        case HP_TXBUFF:
-        {
-            if (s->txsize == 0) {
-                printf("error with txbuff!!!\n");
-                break;
-            }
-
-            s->txbufferaccu[s->txbufferaccu_offset] = val;
-            s->txbufferaccu_offset++;
-            if (s->txbufferaccu_offset >= s->txsize) {
-                qemu_chr_write(vmchannel_hds[s->index].vmchannel_hd, s->txbufferaccu, s->txsize);
-                s->txbufferaccu_offset = 0;
-                s->txsize = 0;
-            }
-            break;
-        }
-        default:
-        {
-            printf("hp_ioport_write to unhandled address!!!\n");
-        }
-    }
-}
-
-static uint32_t hp_ioport_read(void *opaque, uint32_t addr)
-{
-    HypercallState *s = opaque;
-    int ret;
-
-    addr &= 0xff;
-#ifdef HYPERCALL_DEBUG
-    // Since HSR_REGISTER is being repeatedly read in the guest ISR we don't print it
-    if (addr != HSR_REGISTER)
-        printf("%s: addr=0x%x", __FUNCTION__, addr);
-#endif
-
-    if (addr >= offsetof(HypercallState, RxBuff) )
-    {
-        int RxBuffOffset = addr - (offsetof(HypercallState, RxBuff));
-        ret = s->RxBuff[RxBuffOffset];
-#ifdef HYPERCALL_DEBUG
-    printf(" val=%x\n", ret);
-#endif
-        return ret;
-    }
-
-    switch (addr)
-    {
-    case HSR_REGISTER:
-        ret = s->hsr;
-        if (ret & HSR_VDR) {
-            s->hsr &= ~HSR_VDR;
-        }
-        break;
-    case HP_RXSIZE:
-        ret = s->rxsize;
-        break;
-
-    default:
-        ret = 0x00;
-        break;
-    }
-#ifdef HYPERCALL_DEBUG
-    printf(" val=%x\n", ret);
-#endif
-    return ret;
-}
-
-/***********************************************************/
-/* PCI Hypercall definitions */
-
-typedef struct PCIHypercallState {
-    PCIDevice dev;
-    HypercallState hp;
-} PCIHypercallState;
-
-static void hp_map(PCIDevice *pci_dev, int region_num, 
-                       uint32_t addr, uint32_t size, int type)
-{
-    PCIHypercallState *d = (PCIHypercallState *)pci_dev;
-    HypercallState *s = &d->hp;
-
-    register_ioport_write(addr, HYPERCALL_IOPORT_SIZE, 1, hp_ioport_write, s);
-    register_ioport_read(addr, HYPERCALL_IOPORT_SIZE, 1, hp_ioport_read, s);
-
-}
-
-
-static void hypercall_update_irq(HypercallState *s)
-{
-    /* PCI irq */
-    qemu_set_irq(s->pci_dev->irq[0], !(s->hcr & HCR_DI));
-}
-
-static void hc_save(QEMUFile* f,void* opaque)
-{
-    HypercallState* s=(HypercallState*)opaque;
-
-    pci_device_save(s->pci_dev, f);
-
-    qemu_put_be32s(f, &s->hcr);
-    qemu_put_be32s(f, &s->hsr);
-    qemu_put_be32s(f, &s->txsize);
-    qemu_put_be32s(f, &s->txbuff);
-    qemu_put_be32s(f, &s->rxsize);
-    qemu_put_buffer(f, s->RxBuff, HP_MEM_SIZE);
-    qemu_put_buffer(f, s->txbufferaccu, HP_MEM_SIZE);
-    qemu_put_be32s(f, &s->txbufferaccu_offset);
-    qemu_put_be32s(f, &s->irq);
-    qemu_put_be32s(f, &s->index);
-
-}
-
-static int hc_load(QEMUFile* f,void* opaque,int version_id)
-{
-    HypercallState* s=(HypercallState*)opaque;
-    int ret;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    ret = pci_device_load(s->pci_dev, f);
-    if (ret < 0)
-        return ret;
-
-    qemu_get_be32s(f, &s->hcr);
-    qemu_get_be32s(f, &s->hsr);
-    qemu_get_be32s(f, &s->txsize);
-    qemu_get_be32s(f, &s->txbuff);
-    qemu_get_be32s(f, &s->rxsize);
-    qemu_get_buffer(f, s->RxBuff, HP_MEM_SIZE);
-    qemu_get_buffer(f, s->txbufferaccu, HP_MEM_SIZE);
-    qemu_get_be32s(f, &s->txbufferaccu_offset);
-    qemu_get_be32s(f, &s->irq);
-    qemu_get_be32s(f, &s->index);
-
-    return 0;
-}
-
-static void pci_hypercall_single_init(PCIBus *bus, uint32_t deviceid, uint32_t index)
-{
-    PCIHypercallState *d;
-    HypercallState *s;
-    uint8_t *pci_conf;
-    char name[sizeof("HypercallX")];
-
-    sprintf(name, "Hypercall%d", index);
-
-#ifdef HYPERCALL_DEBUG
-    printf("%s, devicename:%s\n", __FUNCTION__, name);
-#endif
-
-    // If the vmchannel wasn't initialized, we don't want the Hypercall device in the guest
-    if (use_hypercall_dev == 0) {
-        return;
-    }
-
-    d = (PCIHypercallState *)pci_register_device(bus,
-                                                 name, sizeof(PCIHypercallState),
-                                                 -1,
-                                                 NULL, NULL);
-
-    pci_conf = d->dev.config;
-    pci_conf[0x00] = 0x02; // Qumranet vendor ID 0x5002
-    pci_conf[0x01] = 0x50;
-    pci_conf[0x02] = deviceid & 0x00ff;
-    pci_conf[0x03] = (deviceid & 0xff00) >> 8;
-
-    pci_conf[0x09] = 0x00; // ProgIf
-    pci_conf[0x0a] = 0x00; // SubClass
-    pci_conf[0x0b] = 0x05; // BaseClass
-
-    pci_conf[0x0e] = 0x00; // header_type
-    pci_conf[0x3d] = 1; // interrupt pin 0
-
-    pci_register_io_region(&d->dev, 0, HYPERCALL_IOPORT_SIZE,
-                           PCI_ADDRESS_SPACE_IO, hp_map);
-    s = &d->hp;
-    pHypercallStates[index] = s;
-    s->index = index;
-    s->irq = 16; /* PCI interrupt */
-    s->pci_dev = (PCIDevice *)d;
-
-    hp_reset(s);
-    register_savevm(name, index, 1, hc_save, hc_load, s);
-}
-
-void pci_hypercall_init(PCIBus *bus)
-{
-    int i;
-
-    // loop devices & call pci_hypercall_single_init with device id's
-    for(i = 0; i < MAX_VMCHANNEL_DEVICES; i++){
-        if (vmchannel_hds[i].vmchannel_hd) {
-            pci_hypercall_single_init(bus, vmchannel_hds[i].deviceid, i);
-        }
-    }
-}
-
-static int vmchannel_can_read(void *opaque)
-{
-    return 128;
-}
-
-static void vmchannel_event(void *opaque, int event)
-{
-
-#ifdef HYPERCALL_DEBUG
-    // if index is to be used outside the printf, take it out of the #ifdef block!
-    long index = (long)opaque;
-    printf("%s index:%ld, got event %i\n", __FUNCTION__, index, event);
-#endif
-    
-    return;
-}
-
-// input from vmchannel outside caller
-static void vmchannel_read(void *opaque, const uint8_t *buf, int size)
-{
-    int i;
-    long index = (long)opaque;
-
-#ifdef HYPERCALL_DEBUG    
-    printf("vmchannel_read buf size:%d\n", size);
-#endif
-
-    // if the hypercall device is in interrupts disabled state, don't accept the data
-    if (pHypercallStates[index]->hcr & HCR_DI) {
-        return;
-    }
-
-    for(i = 0; i < size; i++) {
-        pHypercallStates[index]->RxBuff[i] = buf[i];
-    }
-    pHypercallStates[index]->rxsize = size;
-    pHypercallStates[index]->hsr = HSR_VDR;
-    hypercall_update_irq(pHypercallStates[index]);
-}
-
-void vmchannel_init(CharDriverState *hd, uint32_t deviceid, uint32_t index)
-{
-#ifdef HYPERCALL_DEBUG
-    printf("vmchannel_init, index=%d, deviceid=0x%x\n", index, deviceid);
-#endif
-
-    vmchannel_hds[index].deviceid = deviceid;
-    vmchannel_hds[index].vmchannel_hd = hd;
-   
-    use_hypercall_dev = 1;
-    qemu_chr_add_handlers(vmchannel_hds[index].vmchannel_hd, vmchannel_can_read, vmchannel_read,
-                          vmchannel_event, (void *)(long)index);
-}
diff --git a/qemu/hw/hypercall.h b/qemu/hw/hypercall.h
deleted file mode 100644
index 97434a7..0000000
--- a/qemu/hw/hypercall.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * QEMU-KVM Hypercall emulation
- * 
- * Copyright (c) 2003-2004 Fabrice Bellard
- * Copyright (c) 2006 Qumranet
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#define HCR_REGISTER    0x00  // Hypercall Command Register WR
-#define HSR_REGISTER    0x04  // Hypercall Status Register RD
-#define HP_TXSIZE       0x08
-#define HP_TXBUFF       0x0c
-#define HP_RXSIZE       0x10
-#define HP_RXBUFF       0x14
-
-// HCR_REGISTER commands
-#define HCR_DI		1 // disable interrupts
-#define HCR_EI		2 // enable interrupts
-#define HCR_GRS		4 // Global reset
-#define HCR_RESET	(HCR_GRS|HCR_DI)
-
-
-// Bits in HSR_REGISTER
-#define HSR_VDR		0x01  // vmchannel Data is ready to be read
-
-#define HP_MEM_SIZE    0xE0
-
-
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index d578e68..da60199 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -1055,10 +1055,6 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
     }
 
     qemu_system_hot_add_init(cpu_model);
-#define USE_HYPERCALL
-#ifdef USE_HYPERCALL
-    pci_hypercall_init(pci_bus);
-#endif
 
     if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
         fprintf(stderr, "qemu: too many IDE bus\n");
diff --git a/qemu/sysemu.h b/qemu/sysemu.h
index 993d67b..f03b022 100644
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -172,12 +172,6 @@ void drive_hot_add(int pcibus, const char *devfn_string, const char *opts);
 void device_hot_remove(int pcibus, int slot);
 void device_hot_remove_success(int pcibus, int slot);
 
-/* vmchannel devices */
-
-#define MAX_VMCHANNEL_DEVICES 4
-void pci_hypercall_init(PCIBus *bus);
-void vmchannel_init(CharDriverState *hd, uint32_t deviceid, uint32_t index);
-
 /* serial ports */
 
 #define MAX_SERIAL_PORTS 4
diff --git a/qemu/vl.c b/qemu/vl.c
index 7cc670b..e76396f 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -199,8 +199,6 @@ int graphic_depth = 15;
 int full_screen = 0;
 int no_frame = 0;
 int no_quit = 0;
-int balloon_used = 0;
-CharDriverState *vmchannel_hds[MAX_VMCHANNEL_DEVICES];
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 #ifdef TARGET_I386
@@ -7944,8 +7942,6 @@ static void help(int exitcode)
            "\n"
            "Debug/Expert options:\n"
            "-monitor dev    redirect the monitor to char device 'dev'\n"
-           "-vmchannel di:DI,dev  redirect the hypercall device with device id DI, to char device 'dev'\n"
-           "-balloon dev    redirect the balloon hypercall device to char device 'dev'\n"
            "-serial dev     redirect the serial port to char device 'dev'\n"
            "-parallel dev   redirect the parallel port to char device 'dev'\n"
            "-pidfile file   Write PID to 'file'\n"
@@ -8069,8 +8065,6 @@ enum {
     QEMU_OPTION_std_vga,
     QEMU_OPTION_echr,
     QEMU_OPTION_monitor,
-    QEMU_OPTION_balloon,
-    QEMU_OPTION_vmchannel,
     QEMU_OPTION_serial,
     QEMU_OPTION_parallel,
     QEMU_OPTION_loadvm,
@@ -8187,8 +8181,6 @@ const QEMUOption qemu_options[] = {
     { "localtime", 0, QEMU_OPTION_localtime },
     { "std-vga", 0, QEMU_OPTION_std_vga },
     { "monitor", 1, QEMU_OPTION_monitor },
-    { "balloon", 1, QEMU_OPTION_balloon },
-    { "vmchannel", 1, QEMU_OPTION_vmchannel },
     { "echr", HAS_ARG, QEMU_OPTION_echr },
     { "monitor", HAS_ARG, QEMU_OPTION_monitor },
     { "serial", HAS_ARG, QEMU_OPTION_serial },
@@ -8542,8 +8534,6 @@ int main(int argc, char **argv)
     const char *monitor_device;
     const char *serial_devices[MAX_SERIAL_PORTS];
     int serial_device_index;
-    char vmchannel_devices[MAX_VMCHANNEL_DEVICES][128];
-    int vmchannel_device_index;
     const char *parallel_devices[MAX_PARALLEL_PORTS];
     int parallel_device_index;
     const char *loadvm = NULL;
@@ -8609,10 +8599,6 @@ int main(int argc, char **argv)
     translation = BIOS_ATA_TRANSLATION_AUTO;
     monitor_device = "vc";
 
-    for(i = 0; i < MAX_VMCHANNEL_DEVICES; i++)
-        vmchannel_devices[i][0] = '\0';
-    vmchannel_device_index = 0;
-
     serial_devices[0] = "vc:80Cx24C";
     for(i = 1; i < MAX_SERIAL_PORTS; i++)
         serial_devices[i] = NULL;
@@ -9004,28 +8990,6 @@ int main(int argc, char **argv)
             case QEMU_OPTION_monitor:
                 monitor_device = optarg;
                 break;
-            case QEMU_OPTION_balloon:
-                if (vmchannel_device_index >= MAX_VMCHANNEL_DEVICES) {
-                    fprintf(stderr, "qemu: too many balloon/vmchannel devices\n");
-                    exit(1);
-                }
-                if (balloon_used) {
-                    fprintf(stderr, "qemu: only one balloon device can be used\n");
-                    exit(1);
-                }
-                sprintf(vmchannel_devices[vmchannel_device_index],"di:cdcd,%s", optarg);
-                vmchannel_device_index++;
-                balloon_used = 1;
-                break;
-            case QEMU_OPTION_vmchannel:
-                if (vmchannel_device_index >= MAX_VMCHANNEL_DEVICES) {
-                    fprintf(stderr, "qemu: too many balloon/vmchannel devices\n");
-                    exit(1);
-                }
-                pstrcpy(vmchannel_devices[vmchannel_device_index], 
-                        sizeof(vmchannel_devices[0]), optarg);
-                vmchannel_device_index++;
-                break;
             case QEMU_OPTION_serial:
                 if (serial_device_index >= MAX_SERIAL_PORTS) {
                     fprintf(stderr, "qemu: too many serial ports\n");
@@ -9535,31 +9499,6 @@ int main(int argc, char **argv)
         monitor_init(monitor_hd, !nographic);
     }
 
-    for(i = 0; i < MAX_VMCHANNEL_DEVICES; i++) {
-        const char *devname = vmchannel_devices[i];
-        if (devname[0] != '\0' && strcmp(devname, "none")) {
-            int devid;
-            char *termn;
-
-            if (strstart(devname, "di:", &devname)) {
-                devid = strtol(devname, &termn, 16);
-                devname = termn + 1;
-            }
-            else {
-                fprintf(stderr, "qemu: could not find vmchannel device id '%s'\n", 
-                        devname);
-                exit(1);
-            }
-            vmchannel_hds[i] = qemu_chr_open(devname);
-            if (!vmchannel_hds[i]) {
-                fprintf(stderr, "qemu: could not open vmchannel device '%s'\n", 
-                        devname);
-                exit(1);
-            }
-            vmchannel_init(vmchannel_hds[i], devid, i);
-        }
-    }
-
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         const char *devname = serial_devices[i];
         if (devname && strcmp(devname, "none")) {

^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2008-07-20 14:20 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-17 20:28 [PATCH 1/5] Remove hypercall device Anthony Liguori
2008-07-17 20:28 ` [PATCH 2/5] Remove duplicate monitor definition Anthony Liguori
2008-07-17 20:28 ` [PATCH 3/5] Remove whitespace in VMDK code Anthony Liguori
2008-07-19  7:45   ` Avi Kivity
2008-07-19 14:37     ` Anthony Liguori
2008-07-20  8:47       ` Avi Kivity
2008-07-20 14:19         ` Anthony Liguori
2008-07-17 20:28 ` [PATCH 4/5] Remove unnecessary definition of hack_around_tap Anthony Liguori
2008-07-17 20:28 ` [PATCH 5/5] Remove change to TARGET_PAGE_SIZE Anthony Liguori
2008-07-19  7:50   ` Avi Kivity
2008-07-19  7:49 ` [PATCH 1/5] Remove hypercall device Avi Kivity

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.