Repair Linux MBR after Windows install

Situation

After installing Windows alongside Linux, GRUB has been replaced by the Windows bootloader. How do you get GRUB back into the MBR?

Note „has been“. When openSUSE is installed according to recommendation to keep a neutral MBR that Grub will have been installed to a partition rather than the MBR, which will result in a simpler „repair“ procedure..

Procedure

You have to make sure to be able to boot into openSUSE. You can do this either by using the Rescue System mode on the installation DVD or by using a CD withPlop Boot Manager or Super Grub Disk, for example. Note that you can let boot any ISO on USB with UNetbootin. Then you can repair the Master Boot Record with a few commands:

If using grub2 (default on openSUSE 13.1)

Open a terminal and type commands. Firstly elevate your priviledges (not required in Rescue System mode):

sudo -i

Figure out from the partition table what is your (main) linux partition, e.g. /dev/sda3:

fdisk -l

Then type:

mount /dev/sda3 /mnt
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc # maybe superfluous
mount --bind /sys /mnt/sys # maybe superfluous
mkdir /mnt/mounts # could be needed if booted with rescue openSUSE 13.1
mount --rbind /mounts /mnt/mounts # could be needed if booted with rescue openSUSE 13.1

If this preparation went well, perform the actual change:

chroot /mnt
grub2-install /dev/sda
exit

And if that succeeded,

reboot

If using legacy grub

Open a terminal and type (no ’sudo‘ is required in Rescue System mode):

 sudo /usr/sbin/grub

Then execute the following commands:

 grub> find /boot/grub/stage2 (will show the path of actual grub installation, you will need on the next step)
 grub> root (hdx,y)
 grub> setup (hdx)
 grub> quit

Caution: x represents the disk number and y represents the partition number where GRUB stage2 is installed. The numbering starts at 0. For example, if the first command outputs (hd0,5) you should do root (hd0,5) followed by setup (hd0). After rebooting, the GRUB menu should reappear.

This solution was sourced from please_try_again on the forums.

If a neutral MBR was employed

All that is necessary is to use any available partitioning tool to move the boot flag from the Windows partition to the partition to which Grub is installed. This is easily done with FDISK (which calls the boot flag the active flag) from a DOS boot or from DISKPART or Disk Management from a Windows boot, or using one of the partitioning tools from a generic bootable media such as the Ultimate Boot CD or Hiren’s BootCD.

OpenSUSE 13.1 Repository Settings

Repository URL
AMD-Repo von Bruno Friedmann http://geeko.ioda.net/mirror/amd-fglrx/openSUSE_13.1/
Packman Repository http://ftp.gwdg.de/pub/linux/packman/suse/openSUSE_13.1/
openSUSE-13.1-Debug http://download.opensuse.org/debug/distribution/13.1/repo/oss/
openSUSE-13.1-Non-Oss http://download.opensuse.org/debug/distribution/13.1/repo/non-oss/
openSUSE-13.1-Oss http://download.opensuse.org/debug/distribution/13.1/repo/oss/
openSUSE-13.1Source http://download.opensuse.org/source/distribution/13.1/repo/oss/
openSUSE-13.1-Update http://download.opensuse.org/update/13.1/
openSUSE-13.1-Update-Debug http://download.opensuse.org/debug/update/13.1/
openSUSE-13.1-Update-Debug-Non-Oss http://download.opensuse.org/debug/update/13.1-non-oss/
openSUSE-13.1-Update-Non-Oss http://download.opensuse.org/update/13.1-non-oss/

 

Creating a batch class in Dynamics AX 2009

For creating a batch class in Dynamics AX we can start from the Tutorial_RunbaseBatch class,
but here is the explanation for understanding all its methods:

In the classDeclaration, we declare any variable that contains user’s selection or preferences
(for example, the customer account for launch a customer report). Also, we declare other
variables like dialog fields, auxiliar variables, etc. But, the most important feature here, is the #localmacro.CurrentList declaration. This macro helps you to define which variables you want
to save for running the class in batch mode (when not user interaction is available).

class Tutorial_RunbaseBatch extends RunBaseBatch
{
    // Packed variables
    TransDate       transDate;
    CustAccount     custAccount;

    // Dialog fields
    DialogField     dlgCustAccount;
    DialogField     dlgTransDate;

    // Current version
    // We can have different versions for different purposes
    #define.CurrentVersion(1)
    #define.Version1(1)
    #localmacro.CurrentList  // Our current variable list for save user's selected values
        transDate,
        custAccount
    #endmacro
}

 

The macro #define.CurrentVersion(1) and #define.Version1(1) are useful for scaling our class
when we need to change/upgrade it preserving compatibility.

Now two methods: pack and unpack. These methods are used for store and retrieve user’s
preferences and perform the batch operation when none user are available (in batch mode).
Here is the point where we use the macro defined previously:

public container pack()
{
    return [#CurrentVersion,#CurrentList];
}

public boolean unpack(container packedClass)
{
    Version version = RunBase::getVersion(packedClass);
;
    switch (version)
    {
        case #CurrentVersion:
            [version,#CurrentList] = packedClass;
            break;
        //case #otherVersion:
            //[version,#CurrentList, #otherList] = packedClass;
            //break;
        default:
            return false;
    }

    return true;
}
Bacause we need to ask the user about preferences for run this object (report,
 process, query, etc.), we must implement some methods:
– dialog: for build the custom dialog for prompting user’s preferences.
– dialogPostRun: after dialog was created, you can perform other UI tasks here.
– getFromDialog: used for retrive user’s preferences (dialog values).
– validate: here, you can perform a validation for any data entered by the user.
public Object dialog()
{
    DialogRunbase       dialog = super();
    ;
 
    // Creation of our custom dialog fields/controls to ask user for preferences
    dlgTransDate = dialog.addFieldValue(typeid(TransDate),transDate);
    dlgCustAccount = dialog.addFieldValue(typeid(CustAccount),custAccount);

    return dialog;
}

public void dialogPostRun(DialogRunbase dialog)
{
;
    super(dialog);
}

public boolean getFromDialog()
{
    ;

    // Retrieving user's preferences
    transDate   = dlgTransDate.value();
    custAccount = dlgCustAccount.value();

    return super();
}

public boolean validate()
{
    // We can perform some validations here
    if (false)
        return checkFailed("");

    return true;
}
Finally, the main method constructs the object from this batch class, and after
 prompting user and validation was successful, the run method is called to perform
some task (in batch mode if it was selected):
server static Tutorial_RunbaseBatch construct()
{
    return new Tutorial_RunbaseBatch();
}

public void run()
{
    try
    {
        // Obviously, this code is silly, why show something to nobody?
        // remember, this code is running in batch without user interaction
        info(strfmt("Parameters: %1 for %2", transDate, custAccount));
    }
    catch(Exception::Deadlock)
    {
        retry;
    }
    catch(Exception::UpdateConflict)
    {
        throw Exception::UpdateConflict;
    }
    catch
    {
        throw Exception::Error;
    }
}

static void main(Args args)
{
    Tutorial_RunbaseBatch    tutorial_RunBase;
    ;

    // Instanciating this batch class
    tutorial_RunBase = Tutorial_RunbaseBatch::construct();

    // Prompting user and run if all is ok
    if (tutorial_RunBase.prompt())
        tutorial_RunBase.run();
}