Merge pull request #246 from akuker/feature_backend_reserve

Manage scsi id reservations on the rascsi backend; Store drive size instead of blocks; sundry minor fixes
This commit is contained in:
Eric Helgeson 2021-09-24 15:17:56 -05:00 committed by GitHub
commit 4fed455645
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 122 additions and 118 deletions

View File

@ -310,7 +310,7 @@ function setupWiredNetworking() {
echo "Modified /etc/network/interfaces.d/rascsi_bridge"
echo "Configuration completed!"
echo "Please make sure you attach ia DaynaPORT network adapter to the RaSCSI configuration."
echo "Please make sure you attach a DaynaPORT network adapter to the RaSCSI configuration."
echo "Either use the Web UI, or do this on the command line (assuming SCSI ID 6): \"rascsi -ID 6 -t scdp $LAN_INTERFACE\""
echo ""
echo "We need to reboot your Pi"
@ -397,20 +397,25 @@ function setupWirelessNetworking() {
}
function reserveScsiIds() {
if [ ! -f /etc/systemd/system/rascsi-web.service ]; then
echo "This feature depends on the RaSCSI Web UI being installed. Please install RaSCSI Web before continuing."
exit
sudo systemctl stop rascsi
echo "WARNING: This will override any existing modifications to rascsi.service!"
echo "Please type the SCSI ID(s) that you want to reserve and press Enter:"
echo "The input should be numbers between 0 and 7 separated by commas, e.g. \"0,1,7\" for IDs 0, 1, and 7."
echo "Leave empty to make all IDs available."
read -r RESERVED_IDS
if [[ $RESERVED_IDS = "" ]]; then
sudo sed -i /^ExecStart=/d /etc/systemd/system/rascsi.service
sudo sed -i "8 i ExecStart=/usr/local/bin/rascsi" /etc/systemd/system/rascsi.service
else
sudo sed -i /^ExecStart=/d /etc/systemd/system/rascsi.service
sudo sed -i "8 i ExecStart=/usr/local/bin/rascsi -r $RESERVED_IDS" /etc/systemd/system/rascsi.service
fi
sudo systemctl stop rascsi-web
echo "Please type the SCSI ID(s) that you want to reserve and press Enter:"
echo "The input should be a string of digits without separators, e.g. \"017\" for IDs 0, 1, and 7."
read -r RESERVED_IDS
sudo sed -i /^ExecStart=/d /etc/systemd/system/rascsi-web.service
sudo sed -i "8 i ExecStart=/home/pi/RASCSI/src/web/start.sh --reserved_ids=$RESERVED_IDS" /etc/systemd/system/rascsi-web.service
echo "Modified /etc/systemd/system/rascsi.service"
sudo systemctl daemon-reload
sudo systemctl start rascsi-web
sudo systemctl start rascsi
}
function runChoice() {

View File

@ -5,10 +5,17 @@ After=network.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/local/bin/rascsi
# Example: If you want to automatically attach a hard disk at startup, change
# the ExecStart line to:
# ExecStart=/usr/local/bin/rascsi -ID1 /home/pi/images/harddisk.hda
ExecStart=/usr/local/bin/rascsi -r 7
# Example 1: If you want to automatically attach a hard disk at startup,
# say an image called harddisk.hds on SCSI ID 1, change the ExecStart line to:
#
# ExecStart=/usr/local/bin/rascsi -ID1 /home/pi/images/harddisk.hds
#
# Example 2: If you want to reserve SCSI IDs to prevent usage, add '-r' followed by
# comma-separated SCSI ID numbers; for instance IDs 0 and 7:
#
# ExecStart=/usr/local/bin/rascsi -r 0,7
#
# This functionality isn't implmented yet: ExecStop=/usr/local/bin/rasctl -stop
StandardOutput=syslog
StandardError=syslog

View File

@ -5,7 +5,7 @@
"product": "RZ55 (C) DEC",
"revision": "",
"block_size": 512,
"blocks": 660960,
"size": 332308480,
"name": "DEC RZ55",
"file_type": "hds",
"description": "Largest recognized drive on Ultrix 3.0",
@ -17,7 +17,7 @@
"product": "RZ57 (C) DEC",
"revision": "5000",
"block_size": 512,
"blocks": 2050125,
"size": 1037203456,
"name": "DEC RZ57",
"file_type": "hds",
"description": "Largest recognized drive on Ultrix 3.1 - 4.3",
@ -29,11 +29,11 @@
"product": "RZ59 (C) DEC",
"revision": "2000",
"block_size": 512,
"blocks": 17755614,
"size": 9090874368,
"name": "DEC RZ59",
"file_type": "hds",
"description": "Largest recognized drive on OSF/1 3.x - 5.x",
"url": ""
"url": "https://stason.org/TULARC/pc/hard-drives-hdd/dec/RZ74-3570MB-5-25-FH-SCSI2-FAST.html"
},
{
"device_type": "SCHD",
@ -41,7 +41,7 @@
"product": "RZ74 (C) DEC",
"revision": "427H",
"block_size": 512,
"blocks": 6950125,
"size": 3571904000,
"name": "DEC RZ74",
"file_type": "hds",
"description": "Largest recognized drive on Ultrix 4.4 - 4.5",
@ -49,15 +49,15 @@
},
{
"device_type": "SCHD",
"vendor": "HP",
"product": "A2076",
"revision": "DD24",
"vendor": "CONNER",
"product": "CP3200",
"revision": "3.53233",
"block_size": 512,
"blocks": 2621688,
"name": "HP A2076",
"size": 212926464,
"name": "Conner CP3200",
"file_type": "hds",
"description": "Largest recognized drive on HP-UX 8.0",
"url": "http://www.bitsavers.org/pdf/micropolis/105389b_1528_1991.pdf"
"description": "Very commonly used with Sun-4 systems",
"url": ""
},
{
"device_type": "SCHD",
@ -65,22 +65,34 @@
"product": "C3010",
"revision": "6.0",
"block_size": 512,
"blocks": 3905792,
"size": 2003032064,
"name": "HP C3010",
"file_type": "hds",
"description": "Largest recognized drive on HP-UX 9.0",
"url": "https://stason.org/TULARC/pc/hard-drives-hdd/hewlett-packard/HP-C3010-001-2003MB-5-25-FH-SCSI2-FAST.html"
},
{
"device_type": "SCHD",
"vendor": "MICROP",
"product": "1528-15MD1066702",
"revision": "DD24",
"block_size": 512,
"size": 1342304256,
"name": "Micropolis 1528",
"file_type": "hds",
"description": "Largest recognized drive on HP-UX 8.0",
"url": "https://parisc.wiki.kernel.org/images-parisc/0/06/980723ng.pdf"
},
{
"device_type": "SCHD",
"vendor": "MICROP",
"product": "1325",
"revision": "",
"block_size": 512,
"blocks": 270336,
"size": 70885376,
"name": "Micropolis 1325",
"file_type": "hds",
"description": "Largest predefined on SunOS 2; Microp 1325 is actually an ESDI disk on an adapter.",
"description": "Largest predefined on SunOS 2",
"url": "https://stason.org/TULARC/pc/hard-drives-hdd/micropolis/1325-69MB-5-25-FH-MFM-ST506.html"
},
{
@ -89,11 +101,11 @@
"product": "1588T",
"revision": "",
"block_size": 512,
"blocks": 651840,
"name": "Micropolis 1588-15",
"size": 666324480,
"name": "Micropolis 1588T",
"file_type": "hds",
"description": "Largest predefined on SunOS 3/4 (Sun-3)",
"url": ""
"url": "https://stason.org/TULARC/pc/hard-drives-hdd/micropolis/1588-667MB-5-25-FH-SCSI1-SE.html"
},
{
"device_type": "SCHD",
@ -101,7 +113,7 @@
"product": "ST32430N SUN2.1G",
"revision": "0444",
"block_size": 512,
"blocks": 4197405,
"size": 2149071360,
"name": "Seagate SUN2.1G",
"file_type": "hds",
"description": "Largest predefined for SunOS 4 (Sun-4) and Solaris 2.0-2.3",
@ -113,7 +125,7 @@
"product": "ST34371W SUN4.2G",
"revision": "7462",
"block_size": 512,
"blocks": 8380800,
"size": 4290969600,
"name": "Seagate SUN4.2G",
"file_type": "hds",
"description": "Recommended for Solaris 2.4+",
@ -125,7 +137,7 @@
"product": "ST39173W SUN9.0G",
"revision": "2815",
"block_size": 512,
"blocks": 17689267,
"size": 9056904192,
"name": "Seagate SUN9.0G",
"file_type": "hds",
"description": "Recommended for Solaris 2.4+",
@ -137,7 +149,7 @@
"product": "ST914603SSUN146G",
"revision": "0B70",
"block_size": 512,
"blocks": 286739329,
"size": 146789695488,
"name": "Seagate SUN146G",
"file_type": "hds",
"description": "Recommended for Solaris 2.4+",
@ -149,10 +161,22 @@
"product": "FIREBALL540S",
"revision": "",
"block_size": 512,
"blocks": 1065235,
"size": 545400320,
"name": "Quantum Fireball 540S",
"file_type": "hds",
"description": "Recommended for older Macintosh systems. Recognized by Apple HD SC Setup.",
"description": "Recommended for older Macintosh systems.",
"url": ""
},
{
"device_type": "SCHD",
"vendor": "MINSCRIB",
"product": " M8425 - SCSI",
"revision": "209A",
"block_size": 512,
"size": 20994048,
"name": "Miniscribe M8425",
"file_type": "hds",
"description": "Recognized by unpatched Apple HD SC Setup.",
"url": ""
},
{
@ -161,10 +185,22 @@
"product": "FIREBALL ST4.3S",
"revision": "0F0C",
"block_size": 512,
"blocks": 8471232,
"size": 4337270784,
"name": "Quantum Fireball ST4.3S",
"file_type": "hds",
"description": "Recommended for Macintosh System 6 or later. Recognized by Apple HD SC Setup.",
"description": "Recommended for MacOS 8.1 or later.",
"url": ""
},
{
"device_type": "SCHD",
"vendor": "SEAGATE",
"product": "ST32550N",
"revision": "0019",
"block_size": 512,
"size": 2147357696,
"name": "Seagate Barracuda 2GB",
"file_type": "hds",
"description": "2GB is the largest partition size of HFS on older Macs.",
"url": ""
},
{
@ -173,7 +209,7 @@
"product": "ZIP 100",
"revision": "D.13",
"block_size": 512,
"blocks": 196608,
"size": 100663296,
"name": "Iomega ZIP 100",
"file_type": "hdr",
"description": "Removable Iomega ZIP drive, 100MB capacity",
@ -185,7 +221,7 @@
"product": "ZIP 250",
"revision": "D.58",
"block_size": 512,
"blocks": 489532,
"size": 250640384,
"name": "Iomega ZIP 250",
"file_type": "hdr",
"description": "Removable Iomega ZIP drive, 250MB capacity",
@ -197,7 +233,7 @@
"product": "JAZ 2GB",
"revision": "E.16",
"block_size": 512,
"blocks": 3909632,
"size": 2001731584,
"name": "Iomega Jaz 2GB",
"file_type": "hdr",
"description": "Removable Iomega Jaz drive, 2GB capacity",
@ -209,7 +245,7 @@
"product": "SQ5110C",
"revision": "4AA0",
"block_size": 512,
"blocks": 173456,
"size": 88809472,
"name": "SyQuest 88MB",
"file_type": "hdr",
"description": "SyQuest removable hard drive cartridges, 88MB capacity",
@ -221,7 +257,7 @@
"product": "CD-ROM XM-3401TA",
"revision": "0283",
"block_size": 512,
"blocks": null,
"size": null,
"name": "Toshiba XM-3401TA",
"file_type": null,
"description": "Boots most SGI, Sun, HP, IBM, DEC etc. Use only with Unix workstations of this vintage.",
@ -233,7 +269,7 @@
"product": "CD-ROM CDU-8012",
"revision": "3.1a",
"block_size": 512,
"blocks": null,
"size": null,
"name": "Sony CDU-8012",
"file_type": null,
"description": "Boots Sun-3. Use only with Unix workstations of this vintage.",
@ -245,7 +281,7 @@
"product": "A1448A",
"revision": "",
"block_size": 512,
"blocks": null,
"size": null,
"name": "HP A1448A",
"file_type": null,
"description": "Recognized by HP-UX. Use only with Unix workstations of this vintage.",
@ -257,7 +293,7 @@
"product": "RRD42 (C) DEC",
"revision": "4.5d",
"block_size": 512,
"blocks": null,
"size": null,
"name": "DEC RRD42",
"file_type": null,
"description": "Boots DECstations and VAXstations. Use only with Unix workstations of this vintage.",

View File

@ -136,7 +136,7 @@ def write_config(file_name):
if device["block_size"] == 0:
device["block_size"] = None
# Convert to a data type that can be serialized
device["params"] = list(device["params"])
device["params"] = dict(device["params"])
dump(devices, json_file, indent=4)
return {"status": True, "msg": f"Successfully wrote to file: {file_name}"}
except (IOError, ValueError, EOFError, TypeError) as e:
@ -155,10 +155,14 @@ def read_config(file_name):
detach_all()
devices = load(json_file)
for row in devices:
process = attach_image(row["id"], device_type=row["device_type"], \
image=row["image"], unit=int(row["un"]), \
params=row["params"], vendor=row["vendor"], product=row["product"], \
revision=row["revision"], block_size=row["block_size"])
kwargs = {"device_type": row["device_type"], \
"image": row["image"], "unit": int(row["un"]), \
"vendor": row["vendor"], "product": row["product"], \
"revision": row["revision"], "block_size": row["block_size"]}
params = dict(row["params"])
for p in params.keys():
kwargs[p] = params[p]
process = attach_image(row["id"], **kwargs)
if process["status"] == True:
return {"status": process["status"], "msg": f"Successfully read from file: {file_name}"}
else:

View File

@ -61,6 +61,7 @@ def get_valid_scsi_ids(devices, reserved_ids):
return valid_ids
# TODO: This can probably be deprecated and use list_devices instead
def get_type(scsi_id):
device = proto.PbDeviceDefinition()
device.id = int(scsi_id)
@ -242,18 +243,6 @@ def sort_and_format_devices(devices):
return formatted_devices
def reserve_scsi_ids(reserved_scsi_ids):
'''Sends a command to the server to reserve SCSI IDs. Takes a list of strings as argument.'''
command = proto.PbCommand()
command.operation = proto.PbOperation.RESERVE
command.params["ids"] = ",".join(reserved_scsi_ids)
data = send_pb_command(command.SerializeToString())
result = proto.PbResult()
result.ParseFromString(data)
return {"status": result.status, "msg": result.msg}
def set_log_level(log_level):
'''Sends a command to the server to change the log level. Takes target log level as an argument.'''
command = proto.PbCommand()
@ -314,7 +303,7 @@ def send_over_socket(s, payload):
chunk = s.recv(min(response_length - bytes_recvd, 2048))
if chunk == b'':
from flask import abort
logging.error("Read an empty chunk from the socket. Socket connection may have dropped unexpectedly.")
logging.error("Read an empty chunk from the socket. Socket connection may have dropped unexpectedly. Check if RaSCSI has crashed.")
abort(503, "Lost connection to RaSCSI. Please go back and try again. If the issue persists, please report a bug.")
chunks.append(chunk)
bytes_recvd = bytes_recvd + len(chunk)

View File

@ -1,13 +1,13 @@
bjoern==3.1.0
click==7.1.2
Flask==2.0.1
itsdangerous==2.0.0
Jinja2==3.0.0
itsdangerous==2.0.1
Jinja2==3.0.1
machfs==1.2.4
macresources==1.2
MarkupSafe==2.0.0
MarkupSafe==2.0.1
rsrcfork==1.8.0
waitress==1.4.4
zope.event==4.5.0
zope.interface==5.1.2
protobuf>=3.17.3
protobuf==3.17.3

View File

@ -5,9 +5,7 @@ After=network.target
[Service]
Type=simple
Restart=always
ExecStart=/home/pi/RASCSI/src/web/start.sh --reserved_ids=7
# Use the --reserved_ids argument to define an id or range of ids that will be unavailable for attaching devices.
# The default is 7 for Macintosh. Ex. to reserve IDs 0, 1, and 7 do: --reserved_ids=017
ExecStart=/home/pi/RASCSI/src/web/start.sh
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=RASCSIWEB

View File

@ -2,22 +2,6 @@
set -e
# set -x # Uncomment to Debug
# parse arguments
while [ "$1" != "" ]; do
PARAM=`echo $1 | awk -F= '{print $1}'`
VALUE=`echo $1 | awk -F= '{print $2}'`
case $PARAM in
-r | --reserved_ids)
RESERVED_IDS=$VALUE
;;
*)
echo "ERROR: unknown parameter \"$PARAM\""
exit 1
;;
esac
shift
done
cd $(dirname $0)
# verify packages installed
ERROR=0
@ -72,4 +56,4 @@ else
fi
echo "Starting web server..."
python3 web.py ${RESERVED_IDS}
python3 web.py

View File

@ -131,7 +131,7 @@
<hr/>
<h2>Attach Ethernet Adapter</h2>
<p>Emulates a SCSI DaynaPORT Ethernet Adapter. <a href="https://github.com/akuker/RASCSI/wiki/Dayna-Port-SCSI-Link#-macintosh-setup-instructions">Host drivers required.</a></p>
<p>Leave Interface and Static IP blank for default settings, and input only Interface for DHCP setups.</p>
<p>If you have a DHCP setup, ignore the Static IP fields.</p>
<table style="border: none">
<tr style="border: none">
<td style="border: none; vertical-align:top;">
@ -145,7 +145,7 @@
<label for="ip">Static IP (optional):</label>
<input type="text" name="ip" size="15" placeholder="10.10.20.1" />/
<input type="text" name="mask" size="2" placeholder="24">
<label for="scsi_id">ID:</label>
<label for="scsi_id">SCSI ID:</label>
<select name="scsi_id">
{% for id in scsi_ids %}
<option value="{{id}}">{{id}}</option>
@ -205,8 +205,8 @@
<hr/>
<h2>Download File from web and create HFS CD</h2>
<p>Given a URL this will download a file, create a HFS iso, and mount it on the device id given.</p>
<h2>Download File from web and create HFS CD (Macintosh)</h2>
<p>Given a URL this will download a file, create a HFS iso, and mount it on the device id given. Requires a <a href="https://github.com/akuker/RASCSI/wiki/Drive-Setup#Mounting_CD_ISO_or_MO_images">compatible CD-ROM driver</a>.</p>
<table style="border: none">
<tr style="border: none">
<td style="border: none; vertical-align:top;">

View File

@ -28,7 +28,6 @@ from ractl_cmds import (
eject_by_id,
get_valid_scsi_ids,
detach_all,
reserve_scsi_ids,
get_server_info,
get_network_info,
validate_scsi_id,
@ -101,14 +100,12 @@ def drive_list():
for d in conf:
if d["device_type"] == "SCHD":
d["size"] = d["block_size"] * d["blocks"]
d["size_mb"] = "{:,.2f}".format(d["size"] / 1024 / 1024)
hd_conf.append(d)
elif d["device_type"] == "SCCD":
d["size_mb"] = "N/A"
cd_conf.append(d)
elif d["device_type"] == "SCRM":
d["size"] = d["block_size"] * d["blocks"]
d["size_mb"] = "{:,.2f}".format(d["size"] / 1024 / 1024)
rm_conf.append(d)
@ -141,7 +138,6 @@ def drive_create():
vendor = request.form.get("vendor")
product = request.form.get("product")
revision = request.form.get("revision")
blocks = request.form.get("blocks")
block_size = request.form.get("block_size")
size = request.form.get("size")
file_type = request.form.get("file_type")
@ -160,8 +156,8 @@ def drive_create():
# Creating the drive properties file
from pathlib import Path
file_name = str(Path(file_name).stem) + "." + PROPERTIES_SUFFIX
properties = {"vendor": vendor, "product": product, "revision": revision, \
"blocks": blocks, "block_size": block_size}
properties = {"vendor": vendor, "product": product, \
"revision": revision, "block_size": block_size}
process = write_drive_properties(file_name, properties)
if process["status"] == True:
flash(f"Drive properties file {file_name} created")
@ -312,11 +308,12 @@ def attach():
kwargs = {"image": file_name}
# Validate image type by file name suffix
# Supplementing file ending based image type detection on the backend side
if file_name.lower().endswith(CDROM_FILE_SUFFIX):
kwargs["device_type"] = "SCCD"
elif file_name.lower().endswith(REMOVABLE_FILE_SUFFIX):
kwargs["device_type"] = "SCRM"
elif file_name.lower().endswith(HARDDRIVE_FILE_SUFFIX):
else:
kwargs["device_type"] = "SCHD"
# Attempt to load the device properties file:
@ -331,13 +328,6 @@ def attach():
flash(process["msg"], "error")
return redirect(url_for("index"))
conf = process["conf"]
# CD-ROM drives have no inherent size, so bypass the size check
if kwargs["device_type"] != "SCCD":
conf_file_size = int(conf["blocks"]) * int(conf["block_size"])
if conf_file_size != 0 and conf_file_size > int(file_size):
flash(f"Failed to attach {file_name} to SCSI id {scsi_id}!", "error")
flash(f"The file size {file_size} bytes needs to be at least {conf_file_size} bytes.", "error")
return redirect(url_for("index"))
kwargs["vendor"] = conf["vendor"]
kwargs["product"] = conf["product"]
kwargs["revision"] = conf["revision"]
@ -429,11 +419,8 @@ def restart():
@app.route("/rascsi/restart", methods=["POST"])
def rascsi_restart():
server_info = get_server_info()
rascsi_service("restart")
flash("Restarting RaSCSI Service...")
# Need to turn this into a list of strings from a list of ints
reserve_scsi_ids([str(e) for e in server_info["reserved_ids"]])
return redirect(url_for("index"))
@ -578,12 +565,6 @@ if __name__ == "__main__":
makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True)
app.config["MAX_CONTENT_LENGTH"] = MAX_FILE_SIZE
from sys import argv
if len(argv) >= 2:
# Reserve SCSI IDs on the backend side to prevent use
# Expecting argv as a string of digits such as '017'
reserve_scsi_ids(list(argv[1]))
# Load the default configuration file, if found
from pathlib import Path
default_config_path = Path(base_dir + DEFAULT_CONFIG)