Fix “Unable to install GRUB in /dev/sda” error during installing Ubuntu

Today, I met “Unable to install GRUB in /dev/sda” error during installing Ubuntu 14.04 server:

2

3 Suddenly, I remembered the OS was not installed on /dev/sda, but /dev/sdc:

1 So in “Install the GRUB boot loader on a hard disk” step, I should select No:

4

Then filled /dev/sdc as the right installation hard disk.

5

It worked!

 

 

Why doesn’t Linux device driver need to update file position in read/write functions?

From LDD3, “char drivers” section:

loff_t f_pos;

The current reading or writing position. loff_t is a 64-bit value on all platforms ( long long in gcc terminology). The driver can read this value if it needs to know the current position in the file but should not normally change it; read and write should update a position using the pointer they receive as the last argument instead of acting on filp->f_pos directly. The one exception to this rule is in the llseek method, the purpose of which is to change the file position.

Why “read and write should update a position using the pointer they receive as the last argument instead of acting on filp->f_pos directly“? After checking the kernel code(the version is 3.0), I get the answer.

Use read system call as an example, and others are similar. Firstly, check read code (fs/read_write.c):

SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
    struct file *file;
    ssize_t ret = -EBADF;
    int fput_needed;

    file = fget_light(fd, &fput_needed);
    if (file) {
        loff_t pos = file_pos_read(file);
        ret = vfs_read(file, buf, count, &pos);
        file_pos_write(file, pos);
        fput_light(file, fput_needed);
    }

    return ret;
}

The core part is the following part:

loff_t pos = file_pos_read(file);
ret = vfs_read(file, buf, count, &pos);
file_pos_write(file, pos);

file_pos_read is very simple, just one statement:

static inline loff_t file_pos_read(struct file *file)
{
    return file->f_pos;
}

It returns the current file position.

Then let we see the vfs_read:

ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
    ssize_t ret;

    if (!(file->f_mode & FMODE_READ))
        return -EBADF;
    if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read))
        return -EINVAL;
    if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
        return -EFAULT;

    ret = rw_verify_area(READ, file, pos, count);
    if (ret >= 0) {
        count = ret;
        if (file->f_op->read)
            ret = file->f_op->read(file, buf, count, pos);
        else
            ret = do_sync_read(file, buf, count, pos);
        if (ret > 0) {
            fsnotify_access(file);
            add_rchar(current, ret);
        }
        inc_syscr(current);
    }

    return ret;
}

Exclude a lot of condition checks, the skeleton is just like this:

if (file->f_op->read)
    ret = file->f_op->read(file, buf, count, pos);
else
    ret = do_sync_read(file, buf, count, pos);

If the driver provides theĀ read function, use it, else call do_sync_read. No matter which function is used, the new file position should be updated in the memory which pos points to.

Finally, it is file_pos_write‘s function to update the new position:

static inline void file_pos_write(struct file *file, loff_t pos)
{
    file->f_pos = pos;
}

From the above analysis, we can see that it’s no need for every device driver update the file position, and file_pos_read/write will do this uniformly.Other functions are similar, so we can answer the question posted at the beginning of the article now.

Fix “autoreconf: failed to run autopoint: No such file or directory” issue on Suse

On Suse, when executing “autoreconf -i” command in some repository, it prompts following error:

# autoreconf -i
Can't exec "autopoint": No such file or directory at /usr/share/autoconf/Autom4te/FileUtils.pm line 345.
autoreconf: failed to run autopoint: No such file or directory
autoreconf: autopoint is needed because this package uses Gettext

The solution is installing gettext-tools:

# zypper in gettext-tools
Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following NEW package is going to be installed:
  gettext-tools

1 new package to install.
Overall download size: 1.8 MiB. Already cached: 0 B. After the operation, additional 7.9 MiB will be used.
Continue? [y/n/? shows all options] (y): y
Retrieving package gettext-tools-0.19.2-1.103.x86_64                                                   (1/1),   1.8 MiB (  7.9 MiB unpacked)
Checking for file conflicts: .........................................................................................................[done]
(1/1) Installing: gettext-tools-0.19.2-1.103 .........................................................................................[done] 

Then “autoreconf -i” works!

 

Get SLES needed RPM from OpenSuse

When you build software on SLES, if there is no need RPM provided, you can try to download it from OpenSuse website:https://software.opensuse.org/search . E.g.:

# rpmbuild -bp xen.spec
error: Failed build dependencies:
    figlet is needed by xen-4.5.1_10-1.9.x86_64

When build Xen source code, the SLES doesn’t provide figlet RPM. Download and install this RPM from this link:http://download.opensuse.org/repositories/openSUSE:/13.2/standard/x8664/figlet-2.2.4-12.1.5.x8664.rpm. Then it works!