There are at least three "appropriate" ways to do startup things in Ubuntu (presuming you don't merely want to mount it), listed here in decreasing order of preference:
/etc/rc.local (runlevel change script)
There's also to possibility of using udev rules, but it will be convoluted. I recommend against it. The sysvinit script is overkill for such a small thing, so I'll focus on the other two options. The runlevel change script is simplest (though least preferred), so I'll start there.
/etc/rc.local file is simply executed by the
/etc/init.d/rc.local sysvinit script, which is (by default) executed last upon switching to any normal "on" runlevel (e.g. when you boot normally, but not when you shut down or go to recovery mode). To implement setting up the boot device, just add this at the end of
/etc/rc.local, assuming that your file is called
/srv/diskimage and you wish to use
/dev/loop0 as the loop device:
losetup /dev/loop0 /srv/diskimage
That's really all there is to it. Of course, replace the filenames with whatever works best on your setup.
If you want to be a bit more specific about it, you can create an Upstart job for it that sets it up once the filesystem holding it has been mounted. An example would be the following, assuming that
/srv was the mount point containing your
description "Setup loop devices after filesystems are mounted"
start on mounted MOUNTPOINT=/srv
exec losetup /dev/loop0 /srv/diskimage
This should be simple enough to follow conceptually: The first line is just a comment for human readers, and it's instructions to Upstart to wait until the
/srv filesystem is mounted, execute the losetup process, and consider yourself finished when the process exits successfully (a "task", as opposed to a service that is persistent). Just put those contents in a file matching
/etc/init/*.conf. I would choose
The advantages of Upstart jobs over
/etc/rc.local for such a simple thing are small but important. First,
/etc/rc.local is deprecated, and its use as just a "messy sandbox to get things done" is frowned upon by pretty much everyone these days. Among other reasons for frowning upon its use, some programs that do use that file will simply overwrite the contents, and it's difficult to reconcile different scripts that need to go into the same file. Second, Upstart actually handles the dependency checking for you (making sure the filesystem is mounted first), so if there's a problem mounting the filesystem it won't try to set up the loop device....but will once you've resolved and mounted it. Third, Upstart is vastly more flexible: you can, for instance, have it be smart enough to find an unused loop device, and "emit" that loop device for use in other upstart jobs, similar to how we used the "MOUNTPOINT" variable in this example above.