summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--isys/silo.c636
-rw-r--r--silo.py197
2 files changed, 833 insertions, 0 deletions
diff --git a/isys/silo.c b/isys/silo.c
new file mode 100644
index 000000000..072dc4314
--- /dev/null
+++ b/isys/silo.c
@@ -0,0 +1,636 @@
+/* silo.c: Conversions between SCSI and IDE disk names
+ * and OpenPROM fully qualified paths.
+ *
+ * Copyright (C) 1999 Jakub Jelinek <jakub@redhat.com>
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * public license.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <asm/openpromio.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+
+#ifndef OPROMSETCUR
+#define OPROMSETCUR 0x20004FF0
+#define OPROMPCI2NODE 0x20004FF1
+#define OPROMPATH2NODE 0x20004FF2
+#endif
+
+static int hasaliases;
+static char *promdev = "/dev/openprom";
+static int promfd;
+static int p1275 = 0;
+static int prom_root_node, prom_current_node;
+static int promvers;
+static void (*prom_walk_callback)(int node);
+static char prom_path[1024];
+#define MAX_PROP 128
+#define MAX_VAL (4096-128-4)
+static char buf[4096];
+static char regstr[40];
+#define DECL_OP(size) struct openpromio *op = (struct openpromio *)buf; op->oprom_size = (size)
+
+static int
+prom_setcur(int node) {
+ DECL_OP(sizeof(int));
+
+ if (node == -1) return 0;
+ *(int *)op->oprom_array = node;
+ if (ioctl (promfd, OPROMSETCUR, op) < 0)
+ return 0;
+ prom_current_node = *(int *)op->oprom_array;
+ return *(int *)op->oprom_array;
+}
+
+static int
+prom_getsibling(int node) {
+ DECL_OP(sizeof(int));
+
+ if (node == -1) return 0;
+ *(int *)op->oprom_array = node;
+ if (ioctl (promfd, OPROMNEXT, op) < 0)
+ return 0;
+ prom_current_node = *(int *)op->oprom_array;
+ return *(int *)op->oprom_array;
+}
+
+static int
+prom_getchild(int node) {
+ DECL_OP(sizeof(int));
+
+ if (!node || node == -1) return 0;
+ *(int *)op->oprom_array = node;
+ if (ioctl (promfd, OPROMCHILD, op) < 0)
+ return 0;
+ prom_current_node = *(int *)op->oprom_array;
+ return *(int *)op->oprom_array;
+}
+
+static char *
+prom_getproperty(char *prop, int *lenp) {
+ DECL_OP(MAX_VAL);
+
+ strcpy (op->oprom_array, prop);
+ if (ioctl (promfd, OPROMGETPROP, op) < 0)
+ return 0;
+ if (lenp) *lenp = op->oprom_size;
+ return op->oprom_array;
+}
+
+static int
+prom_getbool(char *prop) {
+ DECL_OP(0);
+
+ *(int *)op->oprom_array = 0;
+ for (;;) {
+ op->oprom_size = MAX_PROP;
+ if (ioctl(promfd, OPROMNXTPROP, op) < 0)
+ return 0;
+ if (!op->oprom_size)
+ return 0;
+ if (!strcmp (op->oprom_array, prop))
+ return 1;
+ }
+}
+
+static int
+prom_pci2node(int bus, int devfn) {
+ DECL_OP(2*sizeof(int));
+
+ ((int *)op->oprom_array)[0] = bus;
+ ((int *)op->oprom_array)[1] = devfn;
+ if (ioctl (promfd, OPROMPCI2NODE, op) < 0)
+ return 0;
+ prom_current_node = *(int *)op->oprom_array;
+ return *(int *)op->oprom_array;
+}
+
+static int
+prom_path2node(char *path) {
+ DECL_OP(MAX_VAL);
+
+ strcpy (op->oprom_array, path);
+ if (ioctl (promfd, OPROMPATH2NODE, op) < 0)
+ return 0;
+ prom_current_node = *(int *)op->oprom_array;
+ return *(int *)op->oprom_array;
+}
+
+#define PW_TYPE_SBUS 1
+#define PW_TYPE_PCI 2
+#define PW_TYPE_EBUS 3
+
+static void
+prom_walk(char *path, int parent, int node, int type) {
+ int nextnode;
+ int len, ntype = type;
+ char *prop;
+
+ prop = prom_getproperty("name", &len);
+ if (prop && len > 0) {
+ if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
+ ntype = PW_TYPE_SBUS;
+ else if (!strcmp(prop, "ebus") && type == PW_TYPE_PCI)
+ ntype = PW_TYPE_EBUS;
+ else if (!strcmp(prop, "pci") && !type)
+ ntype = PW_TYPE_PCI;
+ }
+ *path = '/';
+ strcpy (path + 1, prop);
+ prop = prom_getproperty("reg", &len);
+ if (prop && len >= 4) {
+ unsigned int *reg = (unsigned int *)prop;
+ int cnt = 0;
+ if (!p1275 || (type == PW_TYPE_SBUS))
+ sprintf (regstr, "@%x,%x", reg[0], reg[1]);
+ else if (type == PW_TYPE_PCI) {
+ if ((reg[0] >> 8) & 7)
+ sprintf (regstr, "@%x,%x", (reg[0] >> 11) & 0x1f, (reg[0] >> 8) & 7);
+ else
+ sprintf (regstr, "@%x", (reg[0] >> 11) & 0x1f);
+ } else if (len == 4)
+ sprintf (regstr, "@%x", reg[0]);
+ else
+ sprintf (regstr, "@%x,%x", reg[0] >> 4, reg[1]);
+ for (nextnode = prom_getchild(parent); nextnode; nextnode = prom_getsibling(nextnode)) {
+ prop = prom_getproperty("name", &len);
+ if (prop && len > 0 && !strcmp (path + 1, prop))
+ cnt++;
+ }
+ if (cnt > 1)
+ strcat (path, regstr);
+ }
+
+ prom_walk_callback(node);
+
+ nextnode = prom_getchild(node);
+ if (nextnode)
+ prom_walk(strchr (path, 0), node, nextnode, ntype);
+ nextnode = prom_getsibling(node);
+ if (nextnode)
+ prom_walk(path, parent, nextnode, type);
+}
+
+static int
+prom_init(void) {
+ struct utsname u;
+
+ promfd = open(promdev, O_RDONLY);
+ if (promfd == -1)
+ return -1;
+ prom_root_node = prom_getsibling(0);
+ if (!prom_root_node)
+ return -1;
+
+ if (!uname (&u) && !strcmp (u.machine, "sparc64"))
+ p1275 = 1;
+ return 0;
+}
+
+#define SDSK_TYPE_IDE 1
+#define SDSK_TYPE_SD 2
+#define SDSK_TYPE_PLN 3
+#define SDSK_TYPE_FC 4
+
+static struct sdsk_disk {
+ unsigned int prom_node;
+ unsigned int type, host, hi, mid, lo;
+ unsigned char *prom_name;
+} *hd = NULL, *sd = NULL;
+static int hdlen, sdlen;
+
+static void
+scan_walk_callback(int node) {
+ int nextnode;
+ char *prop;
+ int len, disk;
+ static int v0ctrl = 0;
+
+ for (disk = 0; disk < hdlen + sdlen; disk++) {
+ if (hd[disk].prom_node == node) {
+ switch (hd[disk].type) {
+ case SDSK_TYPE_IDE:
+ for (nextnode = prom_getchild(node); nextnode; nextnode = prom_getsibling(nextnode)) {
+ prop = prom_getproperty("name", &len);
+ if (prop && len > 0 && (!strcmp (prop, "ata") || !strcmp (prop, "disk")))
+ break;
+ }
+ if (!nextnode)
+ continue;
+ if (prop[0] == 'a')
+ sprintf (prop, "/ata@%d,0/cmdk@%d,0", hd[disk].hi, hd[disk].lo);
+ else
+ sprintf (prop, "/disk@%d", hd[disk].hi * 2 + hd[disk].lo);
+ break;
+ case SDSK_TYPE_SD:
+ for (nextnode = prom_getchild(node); nextnode; nextnode = prom_getsibling(nextnode)) {
+ prop = prom_getproperty("name", &len);
+ if (prop && len > 0 && !strcmp (prop, "sd"))
+ break;
+ }
+ if (!nextnode || hd[disk].hi)
+ continue;
+ if (!promvers)
+ sprintf (prop, "sd(%d,%d,", v0ctrl, hd[disk].mid);
+ else
+ sprintf (prop, "/sd@%d,%d", hd[disk].mid, hd[disk].lo);
+ break;
+ case SDSK_TYPE_PLN:
+ sprintf (prop, "/SUNW,pln@%x,%x/SUNW,ssd@%d,%d",
+ hd[disk].lo & 0xf0000000, hd[disk].lo & 0xffffff,
+ hd[disk].hi, hd[disk].mid);
+ break;
+ case SDSK_TYPE_FC:
+ sprintf (prop, "/sf@0,0/ssd@w%08x%08x,%d", hd[disk].hi, hd[disk].mid, hd[disk].lo);
+ break;
+ }
+ hd[disk].prom_name = malloc (strlen (prom_path) + strlen(prop) + 3);
+ if (!hd[disk].prom_name)
+ continue;
+ if (promvers)
+ strcpy (hd[disk].prom_name, prom_path);
+ else
+ hd[disk].prom_name[0] = '\0';
+ strcat (hd[disk].prom_name, prop);
+ }
+ }
+ v0ctrl++;
+}
+
+static int
+scan_ide(void) {
+ DIR * dir;
+ char path[80];
+ char buffer[512];
+ int fd, i, disk;
+ struct dirent * ent;
+ int pci_bus, pci_devfn;
+
+ if (access("/proc/ide", R_OK)) return 0;
+
+ if (!(dir = opendir("/proc/ide"))) {
+ return 1;
+ }
+
+ while ((ent = readdir(dir))) {
+ if (ent->d_name[0] == 'h' && ent->d_name[1] == 'd' &&
+ ent->d_name[2] >= 'a' && ent->d_name[2] <= 'z' &&
+ ent->d_name[3] == '\0') {
+ disk = ent->d_name[2] - 'a';
+ if (disk >= hdlen) {
+ hd = (struct sdsk_disk *)realloc(hd, ((disk&~3)+4)*sizeof(struct sdsk_disk));
+ memset (hd + hdlen, 0, ((disk&~3)+4-hdlen)*sizeof(struct sdsk_disk));
+ hdlen = (disk&~3)+4;
+ }
+ for (i = (disk & ~3); i <= (disk | 3); i++) {
+ if (hd[i].type)
+ break;
+ }
+ if (i > (disk | 3)) {
+ sprintf(path, "/proc/ide/%s", ent->d_name);
+ if (readlink(path, buffer, 512) < 5)
+ continue;
+ if (strncmp(buffer, "ide", 3) ||
+ !isdigit(buffer[3]) ||
+ buffer[4] != '/')
+ continue;
+ buffer[4] = 0;
+ sprintf(path, "/proc/ide/%s/config", buffer);
+ if ((fd = open(path, O_RDONLY)) < 0)
+ continue;
+ i = read(fd, buffer, 50);
+ close(fd);
+ if (i < 50) continue;
+ if (sscanf (buffer, "pci bus %x device %x ",
+ &pci_bus, &pci_devfn) != 2)
+ continue;
+ hd[disk].prom_node = prom_pci2node (pci_bus, pci_devfn);
+ } else
+ hd[disk].prom_node = hd[i].prom_node;
+ hd[disk].type = SDSK_TYPE_IDE;
+ hd[disk].hi = (disk & 2) >> 1;
+ hd[disk].lo = (disk & 1);
+ }
+ }
+
+ closedir(dir);
+
+ return 0;
+}
+
+static int
+scan_scsi(void) {
+ FILE *f;
+ DIR * dir, *dirhba;
+ struct dirent * ent, *enthba;
+ struct stat st;
+ char * p, * q;
+ char buf[512];
+ char path[128];
+ int disk = 0;
+ int host, channel, id, lun;
+ int prom_node, pci_bus, pci_devfn;
+
+ if (access("/proc/scsi/scsi", R_OK)) {
+ return 0;
+ }
+
+ f = fopen("/proc/scsi/scsi", "r");
+ if (f == NULL) return 1;
+
+ if (fgets(buf, sizeof(buf), f) == NULL) {
+ fclose(f);
+ return 1;
+ }
+ if (!strcmp(buf, "Attached devices: none\n")) {
+ fclose(f);
+ return 0;
+ }
+
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ if (sscanf(buf, "Host: scsi%d Channel: %d Id: %d Lun: %d\n",
+ &host, &channel, &id, &lun) != 4)
+ break;
+ if (fgets(buf, sizeof(buf), f) == NULL)
+ break;
+ if (strncmp(buf, " Vendor:", 9))
+ break;
+ if (fgets(buf, sizeof(buf), f) == NULL)
+ break;
+ if (strncmp(buf, " Type: ", 10))
+ break;
+ if (!strncmp(buf+10, "Direct-Access", 13)) {
+ if (disk >= sdlen) {
+ hd = (struct sdsk_disk *)
+ realloc(hd, (hdlen+(disk&~3)+4)*sizeof(struct sdsk_disk));
+ sd = hd + hdlen;
+ memset (sd + sdlen, 0,
+ ((disk&~3)+4-sdlen)*sizeof(struct sdsk_disk));
+ sdlen = (disk&~3)+4;
+ }
+ sd[disk].type = SDSK_TYPE_SD;
+ sd[disk].host = host;
+ sd[disk].hi = channel;
+ sd[disk].mid = id;
+ sd[disk].lo = lun;
+ disk++;
+ }
+ }
+ fclose (f);
+
+ if (!(dir = opendir("/proc/scsi"))) {
+ if (!hdlen && hd) {
+ free(hd);
+ hd = NULL;
+ }
+ sd = NULL;
+ sdlen = 0;
+ return 1;
+ }
+
+ while ((ent = readdir(dir))) {
+ if (!strcmp (ent->d_name, "scsi") || ent->d_name[0] == '.')
+ continue;
+ sprintf (path, "/proc/scsi/%s", ent->d_name);
+ if (stat (path, &st) < 0 || !S_ISDIR (st.st_mode))
+ continue;
+ if (!(dirhba = opendir(path)))
+ continue;
+
+ while ((enthba = readdir(dirhba))) {
+ if (enthba->d_name[0] == '.')
+ continue;
+ host = atoi(enthba->d_name);
+ sprintf (path, "/proc/scsi/%s/%s", ent->d_name, enthba->d_name);
+ f = fopen (path, "r");
+ if (f == NULL) continue;
+
+ if (!strcmp (ent->d_name, "esp") ||
+ !strcmp (ent->d_name, "qlogicpti") ||
+ !strcmp (ent->d_name, "fcal"))
+ p = "PROM node";
+ else if (!strcmp (ent->d_name, "pluto"))
+ p = "serial ";
+ else
+ p = "PCI bus";
+ while (fgets (buf, sizeof(buf), f) != NULL) {
+ q = strstr (buf, p);
+ if (q == NULL) continue;
+ prom_node = 0;
+ switch (p[1]) {
+ case 'R':
+ if (sscanf (q, "PROM node %x", &prom_node) == 1)
+ q = NULL;
+ break;
+ case 'e':
+ if (sscanf (q, "serial 000000%x %*dx%*d on soc%*d port %x PROM node %x",
+ &id, &lun, &prom_node) == 3 &&
+ lun >= 10 && lun <= 11) {
+ q = NULL;
+ }
+ break;
+ case 'C':
+ if (sscanf (q, "PCI bus %x device %x", &pci_bus, &pci_devfn) == 2) {
+ q = NULL;
+ prom_node = prom_pci2node (pci_bus, pci_devfn);
+ }
+ break;
+ }
+ if (q == NULL) {
+ for (disk = 0; disk < sdlen; disk++)
+ if (sd[disk].host == host) {
+ sd[disk].prom_node = prom_node;
+ if (p[1] == 'e') {
+ sd[disk].type = SDSK_TYPE_PLN;
+ sd[disk].lo = (id << 28) | lun;
+ } else if (!strcmp (ent->d_name, "fcal"))
+ sd[disk].type = SDSK_TYPE_FC;
+ }
+ }
+ }
+ if (!strcmp (ent->d_name, "fcal")) {
+ while (fgets (buf, sizeof(buf), f) != NULL) {
+ unsigned long long ll;
+ if (sscanf (buf, " [AL-PA: %*x, Id: %d, Port WWN: %Lx, Node WWN: ", &id, &ll) == 2) {
+ for (disk = 0; disk < sdlen; disk++)
+ if (sd[disk].host == host && sd[disk].mid == id) {
+ sd[disk].hi = ll >> 32;
+ sd[disk].mid = ll;
+ }
+ }
+ }
+ }
+ fclose(f);
+ }
+ closedir(dirhba);
+ }
+ closedir(dir);
+ return 0;
+}
+
+int get_prom_ver(void)
+{
+ FILE *f = fopen ("/proc/cpuinfo","r");
+ int ver = 0;
+ char buffer[1024];
+ char *p;
+
+ if (f) {
+ while (fgets (buffer, 1024, f)) {
+ if (!strncmp (buffer, "promlib", 7)) {
+ p = strstr (buffer, "Version ");
+ if (p) {
+ p += 8;
+ if (*p == '0' || (*p >= '2' && *p <= '3')) {
+ ver = *p - '0';
+ }
+ }
+ break;
+ }
+ }
+ fclose(f);
+ }
+ return ver;
+}
+
+void check_aliases(void) {
+ int nextnode, len;
+ char *prop;
+ hasaliases = 0;
+ for (nextnode = prom_getchild(prom_root_node); nextnode; nextnode = prom_getsibling(nextnode)) {
+ prop = prom_getproperty("name", &len);
+ if (prop && len > 0 && !strcmp (prop, "aliases"))
+ hasaliases = 1;
+ }
+}
+
+int init_sbusdisk(void) {
+ if (prom_init())
+ return -1;
+ promvers = get_prom_ver();
+ check_aliases();
+ scan_ide();
+ scan_scsi();
+ prom_walk_callback = scan_walk_callback;
+ prom_walk(prom_path, prom_root_node, prom_getchild (prom_root_node), 0);
+ close(promfd);
+ return 0;
+}
+
+#ifdef STANDALONE_SILO
+
+int main(void) {
+ int i;
+
+ init_sbusdisk();
+ for (i = 0; i < hdlen; i++) {
+ if (hd[i].type)
+ printf ("hd%c %x %d %d %d\n", i + 'a', hd[i].prom_node,
+ hd[i].hi, hd[i].mid, hd[i].lo);
+ if (hd[i].prom_name) printf ("%s\n", hd[i].prom_name);
+ }
+ for (i = 0; i < sdlen; i++) {
+ if (sd[i].type)
+ if (i < 26)
+ printf ("sd%c %x %d %d %d\n", i + 'a', sd[i].prom_node,
+ sd[i].hi, sd[i].mid, sd[i].lo);
+ else
+ printf ("sd%c%c %x %d %d %d\n", (i / 26) + 'a' - 1, (i % 26) + 'a', sd[i].prom_node,
+ sd[i].hi, sd[i].mid, sd[i].lo);
+ if (sd[i].prom_name) printf ("%s\n", sd[i].prom_name);
+ }
+}
+#else
+
+#include <Python.h>
+
+PyObject *disk2prompath (PyObject *, PyObject *);
+PyObject *has_aliases (void);
+
+static PyMethodDef _siloMethods[] = {
+ { "disk2prompath", disk2prompath, 1 },
+ { "has_aliases", has_aliases, 1 },
+ { NULL, NULL }
+};
+
+void
+init_silo ()
+{
+ PyObject *m;
+ m = Py_InitModule ("_silo", _siloMethods);
+
+ if (init_sbusdisk ())
+ Py_FatalError ("unable to open /dev/openprom");
+ if (PyErr_Occurred ())
+ Py_FatalError ("can't initialize module _silo");
+}
+
+PyObject *
+disk2prompath (PyObject *self, PyObject *args)
+{
+ unsigned char *disk, prompath[1024];
+ int diskno = -1, part;
+
+ if (!PyArg_ParseTuple (args, "s", &disk))
+ return NULL;
+ if (disk[0] == 'h' && disk[1] == 'd' && disk[2] >= 'a' && disk[2] <= 'z') {
+ diskno = disk[2] - 'a';
+ disk += 3;
+ } else if (disk[0] == 's' && disk[1] == 'd' && disk[2] >= 'a' && disk[2] <= 'z') {
+ if (disk[3] >= 'a' && disk[3] <= 'z') {
+ diskno = (disk[2] - 'a' + 1) * 26 + (disk[3] - 'a');
+ disk += 4;
+ } else {
+ diskno = disk[2] - 'a';
+ disk += 3;
+ }
+ if (diskno >= 128)
+ diskno = -1;
+ else
+ diskno += hdlen;
+ }
+ if (diskno == -1)
+ part = -1;
+ else if (!disk[0])
+ part = 0;
+ else {
+ part = atoi (disk);
+ if (part <= 0 || part > 8) part = -1;
+ }
+ if (diskno < 0 || part == -1 ||
+ diskno >= hdlen + sdlen || !hd[diskno].prom_name) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (!promvers)
+ sprintf (prompath, "%s%d)", hd[diskno].prom_name, part ? part - 1 : 2);
+ else {
+ if (part)
+ sprintf (prompath, "%s:%c", hd[diskno].prom_name, part + 'a' - 1);
+ else
+ strcpy (prompath, hd[diskno].prom_name);
+ }
+ return Py_BuildValue ("s", prompath);
+}
+
+PyObject *
+has_aliases (void)
+{
+ return Py_BuildValue ("i", hasaliases);
+}
+
+#endif
diff --git a/silo.py b/silo.py
new file mode 100644
index 000000000..ffe58912f
--- /dev/null
+++ b/silo.py
@@ -0,0 +1,197 @@
+import string
+import os
+import lilo
+import _silo
+
+class SiloInstall:
+ def __init__ (self, todo):
+ self.todo = todo
+ self.linuxalias = None
+ self.bootdevice = None
+
+ def getSiloImages(self):
+ todo = self.todo
+ if not todo.ddruid:
+ raise RuntimeError, "No disk druid object"
+
+ (drives, raid) = todo.ddruid.partitionList()
+
+ # rearrange the fstab so it's indexed by device
+ mountsByDev = {}
+ for loc in todo.mounts.keys():
+ (device, fsystem, reformat) = todo.mounts[loc]
+ mountsByDev[device] = loc
+
+ oldImages = {}
+ for dev in todo.liloImages.keys():
+ oldImages[dev] = todo.liloImages[dev]
+
+ todo.liloImages = {}
+ foundUfs = 0
+ for (dev, devName, type) in drives:
+ # ext2 partitions get listed if
+ # 1) they're /
+ # 2) they're not mounted
+ # and contain /boot of
+ # some Linux installation
+
+ # only list ext2 and ufs partitions
+ if type != 2 and type != 6:
+ continue
+
+ if (mountsByDev.has_key(dev)):
+ if mountsByDev[dev] == '/':
+ todo.liloImages[dev] = ("linux", 2)
+ else:
+ if not oldImages.has_key(dev):
+ todo.liloImages[dev] = ("", type)
+ else:
+ todo.liloImages[dev] = oldImages[dev]
+ # XXX
+ if type == 6:
+ if foundUfs: continue
+ foundUfs = 1
+ todo.liloImages[dev] = ("solaris", type)
+
+ return todo.liloImages
+
+ def getSiloOptions(self):
+ if self.todo.mounts.has_key ('/boot'):
+ bootpart = self.todo.mounts['/boot'][0]
+ else:
+ bootpart = self.todo.mounts['/'][0]
+ i = len (bootpart) - 1
+ while i > 0 and bootpart[i] in string.digits:
+ i = i - 1
+ boothd = bootpart[:i+1]
+
+ return (bootpart, boothd)
+
+ def hasUsableFloppy(self):
+ try:
+ f = open("/proc/devices", "r")
+ except:
+ return 0
+ lines = f.readlines ()
+ f.close ()
+ for line in lines:
+ if string.strip (line) == "2 fd":
+ return 1
+ return 0
+
+ def hasAliases(self):
+ return _silo.has_aliases()
+
+ def disk2PromPath(self,dev):
+ return _silo.disk2prompath(dev)
+
+ def installSilo (self):
+ todo = self.todo
+ silo = LiloConfiguration ()
+
+ if not todo.liloImages:
+ todo.setLiloImages(self.getSiloImages())
+
+ # OK - for this release we need to just blow away the old silo.conf
+ # just like we used to.
+## # on upgrade read in the silo config file
+## if os.access (self.instPath + '/etc/silo.conf', os.R_OK):
+## silo.read (self.instPath + '/etc/silo.conf')
+## elif not todo.liloDevice: return
+
+ (bootpart, boothd) = self.getSiloOptions()
+ smpInstalled = (self.hdList.has_key('kernel-smp') and
+ self.hdList['kernel-smp'].selected)
+
+ if self.mounts.has_key ('/'):
+ (dev, fstype, format) = self.mounts['/']
+ rootDev = dev
+ else:
+ raise RuntimeError, "Installing lilo, but there is no root device"
+
+ args = [ "silo", "-r", todo.instPath ]
+
+ if (todo.liloDevice != "mbr"):
+ args.append("-t")
+
+ i = len (bootpart) - 1
+ while i > 0 and bootpart[i] in digits:
+ i = i - 1
+ silo.addEntry("partition", bootpart[i+1:])
+ silo.addEntry("timeout", "50")
+ silo.addEntry("root", rootDev)
+ silo.addEntry("read-only")
+
+ kernelList = []
+ otherList = []
+
+ main = "linux"
+
+ for (drive, (label, liloType)) in todo.liloImages.items ():
+ if (drive == rootDev) and label:
+ main = label
+ elif label:
+ # FIXME
+ otherList.append (label, "/dev/" + drive)
+
+ silo.addEntry("default", main)
+
+ label = main
+ if (smpInstalled):
+ kernelList.append((main, self.hdList['kernel-smp'], "smp"))
+ label = main + "-up"
+
+ kernelList.append((label, self.hdList['kernel'], ""))
+
+ for (label, kernel, tag) in kernelList:
+ kernelTag = "-%s-%s%s" % (kernel['version'], kernel['release'], tag)
+ initrd = todo.makeInitrd (kernelTag)
+ if rootDev == bootpart:
+ kernelFile = "/boot/vmlinuz" + kernelTag
+ initrdFile = initrd
+ else:
+ kernelFile = "/vmlinuz" + kernelTag
+ initrdFile = initrd[5:]
+
+ sl = LiloConfiguration()
+
+ sl.addEntry("label", label)
+ if os.access (self.instPath + initrd, os.R_OK):
+ sl.addEntry("initrd", initrdFile)
+
+ silo.addImage ("image", kernelFile, sl)
+
+ for (label, device) in otherList:
+ sl = LiloConfiguration()
+ sl.addEntry("label", label)
+ silo.addImage ("other", device, sl)
+
+ # for (siloType, name, config) in silo.images:
+ # # remove entries for missing kernels (upgrade)
+ # if siloType == "image":
+ # if not os.access (self.instPath + name, os.R_OK):
+ # silo.delImage (name)
+ # # remove entries for unbootable partitions
+ # elif siloType == "other":
+ # device = name[5:]
+ # isys.makeDevInode(device, '/tmp/' + device)
+ # if not isys.checkBoot ('/tmp/' + device):
+ # lilo.delImage (name)
+ # os.remove ('/tmp/' + device)
+
+ # pass 2, remove duplicate entries
+ labels = []
+
+ for (siloType, name, config) in silo.images:
+ if not name in labels:
+ labels.append (name)
+ else: # duplicate entry, first entry wins
+ silo.delImage (name)
+
+ silo.write(self.instPath + "/etc/silo.conf")
+
+ # XXX make me "not test mode"
+ if todo.setupFilesystems:
+ iutil.execWithRedirect(todo.instPath + '/sbin/silo' ,
+ args,
+ stdout = None)