+def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
+ """Installs an MBR to a device.
+
+ Retrieve the partition table from "device", install an MBR from
+ the "mbrtemplate" file, set the "partition" (0..3) active, and
+ install the result back to "device".
+
+ "device" may be the name of a file assumed to be a hard disc
+ (or USB stick) image, or something like "/dev/sdb". "partition"
+ must be a number between 0 and 3, inclusive. "mbrtemplate" must
+ be a valid MBR file of at least 440 (439 if ismirbsdmbr) bytes.
+
+ If "ismirbsdmbr", the partitions' active flags are not changed.
+ Instead, the MBR's default value is set accordingly.
+ """
+
+ logging.info("Installing default MBR")
+
+ if not os.path.isfile(mbrtemplate):
+ logging.critical("Error: %s can not be read." % mbrtemplate)
+ raise CriticalException("Error installing MBR (either try --syslinux-mbr or install missing file?)")
+
+ if (partition < 0) or (partition > 3):
+ raise ValueError("partition must be between 0 and 3")
+
+ if ismirbsdmbr:
+ nmbrbytes = 439
+ else:
+ nmbrbytes = 440
+
+ tmpf = tempfile.NamedTemporaryFile()
+
+ logging.debug("executing: dd if='%s' of='%s' bs=512 count=1" % (device, tmpf.name))
+ proc = subprocess.Popen(["dd", "if=%s" % device, "of=%s" % tmpf.name, "bs=512", "count=1"], stderr=file(os.devnull, "r+"))
+ proc.wait()
+ if proc.returncode != 0:
+ raise Exception("error executing dd (first run)")
+
+ logging.debug("executing: dd if=%s of=%s bs=%s count=1 conv=notrunc" % (mbrtemplate, tmpf.name, nmbrbytes))
+ proc = subprocess.Popen(["dd", "if=%s" % mbrtemplate, "of=%s" % tmpf.name, "bs=%s" % nmbrbytes, "count=1", "conv=notrunc"], stderr=file(os.devnull, "r+"))
+ proc.wait()
+ if proc.returncode != 0:
+ raise Exception("error executing dd (second run)")
+
+ mbrcode = tmpf.file.read(512)
+ if len(mbrcode) < 512:
+ raise EOFError("MBR size (%d) < 512" % len(mbrcode))
+
+ if ismirbsdmbr:
+ mbrcode = mbrcode[0:439] + chr(partition) + \
+ mbrcode[440:510] + "\x55\xAA"
+ else:
+ actives = ["\x00", "\x00", "\x00", "\x00"]
+ actives[partition] = "\x80"
+ mbrcode = mbrcode[0:446] + actives[0] + \
+ mbrcode[447:462] + actives[1] + \
+ mbrcode[463:478] + actives[2] + \
+ mbrcode[479:494] + actives[3] + \
+ mbrcode[495:510] + "\x55\xAA"
+
+ tmpf.file.seek(0)
+ tmpf.file.truncate()
+ tmpf.file.write(mbrcode)
+ tmpf.file.close()
+
+ logging.debug("executing: dd if='%s' of='%s' bs=512 count=1 conv=notrunc" % (tmpf.name, device))
+ proc = subprocess.Popen(["dd", "if=%s" % tmpf.name, "of=%s" % device, "bs=512", "count=1", "conv=notrunc"], stderr=file(os.devnull, "r+"))
+ proc.wait()
+ if proc.returncode != 0:
+ raise Exception("error executing dd (third run)")
+ del tmpf
+
+
+def handle_syslinux_mbr(device):
+ """Install syslinux master boot record on given device