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

1
  • So what is your current code for this?
    – Nils
    Aug 9, 2013 at 10:27

3 Answers 3

5
+50

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.

5
  • If I have to add "wait" at the end of for loop then there is no point calling mount command in background
    – SHW
    Aug 9, 2013 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 9, 2013 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, 2013 at 7: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. Aug 12, 2013 at 11:04
  • agree with @frostschutz, try the C version only if performance is an issue.
    – Alex
    Aug 13, 2013 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

1
  • Thnx. I Will check first and then update you
    – SHW
    Aug 12, 2013 at 9:24
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .