# Adding an extra runlevel: doable or not worth the effort?



## ShelLuser (Feb 24, 2014)

Hi gang!

Ever since I started looking into FreeBSD I've been fascinated with the source tree (still am). Sure; it takes its time before you  build your whole OS but the amount of freedom it provides (see src.conf(5) for a good dose of what I'm referring to here) is mind boggling. It has so much potential that all my VPS servers (running FreeBSD) are currently completely build and maintained from the source tree. I heavily favour the approach.

Now; I'm currently in the process of working out a good way to replace two in-house Windows 2k3 servers with FreeBSD. The whole thing has already been decided on; FreeBSD (with Mono, Apache and Samba) can provide a perfect replacement. This isn't merely bias speaking; we tested the whole thing thoroughly.

But there's one problem..  These servers are hardware based; ergo I don't have console access across the network. There are 2 servers, one at my location and one on the other end (VPN). The VPN part is handled by our DrayTek modems, no problems there, but right now I'm wondering if I could manage to continue with using the source tree for my main source of updates.

We all know (or should know) that a good dose of work during updates is done using single user mode. Unfortunately that is not an option for me when talking about a server I don't have physical access to. I discovered /etc/netstart which does indeed just that: start networking operations.

That got me thinking: create a new runlevel which basically starts single user mode but with network support. Then I could start the system in that runlevel, remotely log on and perform all the mergemaster changes I need to.

I'm still in the process of looking into this but still figured I might as well ask too: does this sound reasonable to you guys or do you think I'd better stick to binary updates with the server on the other end?


----------



## kpa (Feb 24, 2014)

*Re: Adding an extra runlevel: doable or not worth the effort*

Yeah, I can see how that would be helpful. However, the BSD init(8) does not know anything about runlevels. The single user mode is just a special invocation of init and the start up scripts that is recognized by the parameters passed to the kernel. Some parts of the SYS V init runlevels are emulated but only the single user mode and the normal multiuser mode are covered.


```
If run as a user process as shown in the second synopsis line, init will
     emulate AT&T System V UNIX behavior, i.e., super-user can specify the
     desired run-level on a command line, and init will signal the original
     (PID 1) init as follows:
     
     Run-level    Signal     Action
     0            SIGUSR2    Halt and turn the power off
     1            SIGTERM    Go to single-user mode
     6            SIGINT     Reboot the machine
     c            SIGTSTP    Block further logins
     q            SIGHUP     Rescan the ttys(5) file
```

It's probably too much work trying to add a new runlevel since the existing architecture doesn't even know about them.


----------



## ondra_knezour (Feb 24, 2014)

*Re: Adding an extra runlevel: doable or not worth the effort*

There are also other options available:
 - Do the update in multiuser mode, not recommended, but done by many (maybe with all services disabled and/or network interface facing the network down)
 - Put the IPMI card in server (my prefered solution)
 - Build and use own upgrade server
 - Examine if the serial port of the server can be connected to your modem or another machine and redirect console there


----------



## J65nko (Feb 25, 2014)

*Re: Adding an extra runlevel: doable or not worth the effort*

Years ago I posted A plan for a remote install and reinstall of FreeBSD The basic idea is to use a small FreeBSD rescue system of 2 or 4 GB. Then SSH into that rescue or bridgehead system and install the actual server in a second slice/partition. 

I have been using this approach for customized, scripted '(sys|bsd)installs' and it has worked quite well for me. Not having done a local or remote source based upgrade for many years, I am not sure whether my approach is viable for your type of upgrade. 

Example output from a MBR/gmirror box where you have to switch systems by modifying the active partition:


```
# gpart show -p

=>       63  781422704    mirror/gm0  MBR  (372G)
         63    8388576  mirror/gm0s1  freebsd  (4G)
    8388639  773034066  mirror/gm0s2  freebsd  [active]  (368G)
  781422705         62                - free -  (31k)

=>      0  8388576   mirror/gm0s1  BSD  (4G)
        0  7905280  mirror/gm0s1a  freebsd-ufs  (3.8G)
  7905280   483296  mirror/gm0s1b  freebsd-swap  (236M)

=>        0  773034066   mirror/gm0s2  BSD  (368G)
          0    2097152  mirror/gm0s2a  freebsd-ufs  (1.0G)
    2097152   20971520  mirror/gm0s2d  freebsd-ufs  (10G)
   23068672   41943040  mirror/gm0s2e  freebsd-ufs  (20G)
   65011712   10485760  mirror/gm0s2f  freebsd-ufs  (5.0G)
   75497472  629145600  mirror/gm0s2g  freebsd-ufs  (300G)
  704643072   62914560  mirror/gm0s2h  freebsd-ufs  (30G)
  767557632    5476434  mirror/gm0s2b  freebsd-swap  (2.6G)
```

And from a GPT formatted system where you can manipulate the "bootme" attribute to boot into the system of your choice:

```
# gpart show -lp
=>       34  104857533     vtbd0  GPT  (50G)
         34        256   vtbd0p1  rescue_boot  (128k)
        290    8388608   vtbd0p2  rescue_root  (4.0G)
    8388898    4194304   vtbd0p3  rescue_swap  (2.0G)
   12583202    2097152   vtbd0p4  df_root  [bootme]  (1.0G)
   14680354    4194304   vtbd0p5  df_tmp  (2.0G)
   18874658    8388608   vtbd0p6  df_www  (4.0G)
   27263266    4194304   vtbd0p7  df_usr  (2.0G)
   31457570   12582912   vtbd0p8  df_ports  (6.0G)
   44040482    2097152   vtbd0p9  df_var  (1.0G)
   46137634    8388608  vtbd0p10  df_mysql  (4.0G)
   54526242    4194304  vtbd0p11  df_swap  (2.0G)
   58720546   46137021  vtbd0p12  df_home  (22G)
```


----------



## ShelLuser (Mar 2, 2014)

*Re: Adding an extra runlevel: doable or not worth the effort*

Thanks for all the hints and comments you guys, much appreciated!

@kpa basically hit the nail on the head up there; when I read init(8) I assumed "oh, runlevels!" and when looking back I suppose I should have known better (apart from init.d and rc.d let's discuss /etc/rc.d/rc3.d (from a Linux CentOS environment)). Better yet; let's not 

Alas; still not sure what direction I'm going to take but right now I'm considering the option to set up my own (fukll) repository or to simply go with "live updates" (but controlled) and only do major updates "on site".

Thanks again, as soon as I make a decision and come up with a specific approach I'll update the thread.


----------

