3

I am doing a project in which I need to mount 100+ loop devices and merge it into AUFS mountpoint As an observation, for sequentially mounting 90 loop devices, it takes 25 seconds.

I am looking for a solution which will minimize time by mounting loop devices in parallel

SHW
  • 14,786
  • 14
  • 66
  • 101

3 Answers3

5

I think this is obvious, but

typeset -i M=1
while [ $M -le 102 ]
  do
    mount mysourcedevice$M targetdir$M &
    let M++
done
wait

Should do the job. The wait will wait until all sub-processess are finished, before executing the next command.

Nils
  • 18,492
  • If I have to add "wait" at the end of for loop then there is no point calling mount command in background – SHW Aug 09 '13 at 12:28
  • 2
    @SHW The wait is outside/after the loop. The loop starts all mounts in paralell. I assume you want to do something after the parallel mounts have finished. – Nils Aug 09 '13 at 21:18
  • Yes...After parallel mounting,I am starting X. and to start X, all loop devices NEED to be mounted beforehand – SHW Aug 10 '13 at 07:30
  • @SHW This code mounts them in parallel; you can do your other stuff after the wait. There isn't anything else to be done. While a C version may be slightly faster still (lacks the overhead of calling mount command a hundred times) it's usually not practical. – frostschutz Aug 12 '13 at 11:04
  • agree with @frostschutz, try the C version only if performance is an issue. – Alex Aug 13 '13 at 11:59
4

Maybe a threaded version could be a bit faster, you've to adjust the mount() parameters yourself.

#include <stdio.h>
#include <pthread.h>
#include <sys/mount.h>
#include <string.h>
#include <errno.h>

#define DEVS 100

static void *mountt(void *d)
{
    int i = (int)d;
    char loop[48], mp[48];

    snprintf(loop, 47, "/dev/loop%d", i);
    snprintf(mp, 47, "/mnt/%d", i);

    if (mount(loop, mp, "ext2", MS_MGC_VAL | MS_RDONLY | MS_NOSUID, "") < 0)
        fprintf(stderr, "mount[%d]: failed: %s\n", i, strerror(errno));

    return NULL;
}

int main(int argc, char **argv)
{
    int i;
    pthread_t tt[DEVS];

    for (i=0; i<DEVS; i++) {
        if (pthread_create( &tt[i], NULL, mountt, (void*)i) != 0)
            fprintf(stderr, "thread create[%d] failed: %s\n", i, strerror(errno));
    }

    for (i=0; i<DEVS; i++)
        pthread_join(tt[i], NULL);

    return 0;
}

gcc -O2 -Wall -o mountt mountt.c -lpthread

Alex
  • 2,586
  • 4
  • 22
  • 30
0

Using GNU Parallel it looks like this:

seq 100 | parallel -j0 mount device{} dir{}

If you have a list of dirs:

parallel -j0 mount device{#} {} ::: dirs*

If you have a list of devices:

parallel -j0 'mkdir -p dir{#}; mount {} dir{#}' ::: device*

GNU Parallel is a general parallelizer and makes is easy to run jobs in parallel on the same machine or on multiple machines you have ssh access to. It can often replace a for loop.

If you have 32 different jobs you want to run on 4 CPUs, a straight forward way to parallelize is to run 8 jobs on each CPU:

Simple scheduling

GNU Parallel instead spawns a new process when one finishes - keeping the CPUs active and thus saving time:

GNU Parallel scheduling

Installation

If GNU Parallel is not packaged for your distribution, you can do a personal installation, which does not require root access. It can be done in 10 seconds by doing this:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

For other installation options see http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Learn more

See more examples: http://www.gnu.org/software/parallel/man.html

Watch the intro videos: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Walk through the tutorial: http://www.gnu.org/software/parallel/parallel_tutorial.html

Sign up for the email list to get support: https://lists.gnu.org/mailman/listinfo/parallel

Ole Tange
  • 35,514