Kindlier way to do network configuration.
authorRichard W.M. Jones <rjones@redhat.com>
Sat, 2 Feb 2008 15:18:02 +0000 (15:18 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Sat, 2 Feb 2008 15:18:02 +0000 (15:18 +0000)
virt-p2v.ml

index f2db828..23b59f0 100755 (executable)
@@ -460,46 +460,39 @@ 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 ...
+(*
+  (* We can run /mnt/root/etc/init.d/network in a chroot environment,
+   * however this won't work directly because the architecture of the
+   * binaries under /mnt/root (eg. /mnt/root/sbin/ip) might not match
+   * the architecture of the live CD kernel.  In particular, a 32 bit
+   * live CD cannot run 64 bit binaries.  So we also have to bind-mount
+   * the live CD's /bin, /sbin, /lib etc. over the equivalents in
+   * /mnt/root.
    *)
-  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.
+  let bind dir =
+    if is_dir dir = Some true then
+      sh ("mount -o bind " ^ quote dir ^ " " ^ quote ("/mnt/root" ^ dir))
+  in
+  let unbind dir =
+    if is_dir dir = Some true then sh ("umount -l " ^ quote ("/mnt/root" ^ dir))
+  in
+  let dirs = [
+    "/bin"; "/sbin"; "/lib"; "/lib64";
+    "/usr/bin"; "/usr/sbin"; "/usr/lib"; "/usr/lib64";
+    "/proc"; "/sys"
+  ] in
+  List.iter bind dirs;
+  let status = shwithstatus "chroot /mnt/root /etc/init.d/network start" in
+  List.iter unbind dirs;
+*)
+
+  (* Simpler way to do the above.
+   * NB. Lazy unmount is required because dhclient keeps its current
+   * directory open on /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 .";
-
+  sh "mount -o bind /mnt/root/etc /etc";
   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";
+  sh "umount -l /etc";
 
   (* Try to ping the remote host to see if this worked. *)
   shfailok ("ping -c 3 " ^ Option.map_default quote "" state.remote_host);