| WSIGNALED i -> failwith (sprintf "shget: command killed by signal %d" i)
| WSTOPPED i -> failwith (sprintf "shget: command stopped by signal %d" i)
-(* Start an interactive shell. *)
+(* Start an interactive shell. Need to juggle file descriptors a bit
+ * because bash write PS1 to stderr (currently directed to the logfile).
+ *)
let shell () =
- shfailok "PS1='\\u@\\h:\\w\\$ ' bash"
+ match fork () with
+ | 0 -> (* child, runs bash *)
+ close stderr;
+ dup2 stdout stderr;
+ (* Sys.command runs 'sh -c' which blows away PS1, so set it late. *)
+ ignore (
+ Sys.command "PS1='\\u@\\h:\\w\\$ ' /bin/bash --norc --noprofile -i"
+ )
+ | _ -> (* parent, waits *)
+ eprintf "waiting for subshell to exit\n%!";
+ ignore (wait ())
(* Some true if is dir/file, Some false if not, None if not found. *)
let is_dir path =
sh (sprintf "dmsetup create %s --table='0 %Ld snapshot /dev/mapper/%s_org %s n 64'"
snapshot_dev sectors snapshot_dev ramdisk)
-(* Try to perform automatic network configuration, assuming a Fedora or RHEL-
- * like root filesystem mounted on /mnt/root.
+(* Try to perform automatic network configuration, assuming a Fedora or
+ * RHEL-like root filesystem mounted on /mnt/root.
*)
let auto_network state =
(* Fedora gives an error if this file doesn't exist. *)
sh "touch /etc/resolv.conf";
+ (* It's tempting to do a 'chroot ...' and run the original
+ * '/etc/init.d/network start' script. However this will not
+ * always work, in particular in the case where the root is
+ * a 64 bit machine and the live CD kernel is 32 bit, and so
+ * cannot run binaries such as /sbin/ifconfig from the root.
+ * Do it the hard way instead ...
+ *)
chdir "/etc/sysconfig";
-
sh "mv network network.saved";
sh "mv networking networking.saved";
sh "mv network-scripts network-scripts.saved";
+ chdir "/etc/init.d";
+ sh "mv network network.saved";
+ sh "mv functions functions.saved";
(* Originally I symlinked these, but that causes dhclient to
* keep open /mnt/root (as its cwd is in network-scripts subdir).
* So now we will copy them recursively instead.
*)
- sh "cp -r /mnt/root/etc/sysconfig/network .";
- sh "cp -r /mnt/root/etc/sysconfig/networking .";
- sh "cp -r /mnt/root/etc/sysconfig/network-scripts .";
+ chdir "/etc/sysconfig";
+ sh "cp -a /mnt/root/etc/sysconfig/network .";
+ sh "cp -a /mnt/root/etc/sysconfig/networking .";
+ sh "cp -a /mnt/root/etc/sysconfig/network-scripts .";
+ chdir "/etc/init.d";
+ sh "cp /mnt/root/etc/init.d/network .";
+ sh "cp /mnt/root/etc/init.d/functions .";
let status = shwithstatus "/etc/init.d/network start" in
+ chdir "/etc/sysconfig";
sh "rm -rf network networking network-scripts";
sh "mv network.saved network";
sh "mv networking.saved networking";
sh "mv network-scripts.saved network-scripts";
+ chdir "/etc/init.d";
+ sh "rm -f network functions";
+ sh "mv network.saved network";
+ sh "mv functions.saved functions";
chdir "/tmp";
(* Output of 'file' command for Linux swap file. *)
let swap = Pcre.regexp "Linux.*swap.*file" in
(* Contents of /etc/redhat-release. *)
- let rhel = Pcre.regexp "(?:Red Hat Enterprise Linux|CentOS|Scientific Linux).*release (\\d+)\\.(\\d+)" in
- let fedora = Pcre.regexp "Fedora.*release (\\d+)\\.(\\d+)" in
+ let rhel = Pcre.regexp "(?:Red Hat Enterprise Linux|CentOS|Scientific Linux).*release (\\d+)(?:\\.(\\d+))?" in
+ let fedora = Pcre.regexp "Fedora.*release (\\d+)" in
(* Contents of /etc/debian_version. *)
let debian = Pcre.regexp "^(\\d+)\\.(\\d+)" in
(* Output of 'file' on certain executables. *)
match lines with
| [] -> (* empty /etc/redhat-release ...? *)
LinuxRoot (UnknownArch, OtherLinux)
- | line::_ ->
+ | line::_ -> (* try to detect OS from /etc/redhat-release *)
try
let subs = Pcre.exec ~rex:rhel line in
let major = int_of_string (Pcre.get_substring subs 1) in
- let minor = int_of_string (Pcre.get_substring subs 2) in
+ let minor =
+ try int_of_string (Pcre.get_substring subs 2)
+ with Not_found -> 0 in
LinuxRoot (UnknownArch, RHEL (major, minor))
with
Not_found | Failure "int_of_string" ->
match lines with
| [] -> (* empty /etc/debian_version ...? *)
LinuxRoot (UnknownArch, OtherLinux)
- | line::_ ->
+ | line::_ -> (* try to detect version from /etc/debian_version *)
try
let subs = Pcre.exec ~rex:debian line in
let major = int_of_string (Pcre.get_substring subs 1) in