[systemd-devel] [PATCH 1/2] Adding unmount functions to be used in shutdown
Karel Zak
kzak at redhat.com
Wed Oct 6 05:17:14 PDT 2010
On Wed, Oct 06, 2010 at 02:05:43AM -0300, Gustavo Sverzut Barbieri wrote:
> +static int swap_list_get(MountPoint **swap_list_head) {
> + FILE *proc_swaps;
> + unsigned int i;
> + int r;
> +
> + if (!(proc_swaps = fopen("/proc/swaps", "re")))
> + return -errno;
> +
> + (void) fscanf(proc_swaps, "%*s %*s %*s %*s %*s\n");
> +
> + for (i = 2;; i++) {
> + MountPoint *swap;
> + char *dev = NULL, *d;
> + int k;
> +
> + if ((k = fscanf(proc_swaps,
> + "%ms " /* device/file */
> + "%*s " /* type of swap */
> + "%*s " /* swap size */
> + "%*s " /* used */
> + "%*s\n", /* priority */
> + &dev)) != 1) {
> +
> + if (k == EOF)
> + break;
> +
> + log_warning("Failed to parse /proc/swaps:%u.", i);
> +
> + free(dev);
> + continue;
> + }
Note that kernel is able to returns "/foo/bar(deleted)" in /proc/swaps
(for moe details util-linux-ng commit dac4cc1dd6b855d781d2ff9689931786ece0acbf).
...
> +static int loopback_list_get(MountPoint **loopback_list_head) {
> + DIR *dir;
> + struct dirent *d;
> + int r;
> +
> + if ((dir = opendir("/sys/class/block")) == NULL)
> + return -errno;
> +
> + while ((d = readdir(dir))) {
> + MountPoint *lb;
> + char buf[PATH_MAX];
> + char *loop;
> +
> + if (!strneq(d->d_name, "loop", 4))
> + continue;
> +
> + snprintf(buf, sizeof(buf), "/dev/%s", d->d_name);
> + if (access(buf, R_OK) != 0)
> + continue;
what about /dev/loop/<N> ?
> +static int mount_points_list_umount(MountPoint **mount_point_list_head) {
> + MountPoint *mp, *mp_next;
> + int failed = 0;
> +
> + LIST_FOREACH_SAFE(mount_point, mp, mp_next, *mount_point_list_head) {
you have to umount filesystems in reverse order, it means /foo/bar
before /foo, it's also possible that on the same mountpoint are
mounted two different filesystems.
> + if (streq(mp->path, "/"))
> + continue;
> +
> + /* Trying to umount. Forcing to umount if busy (only for NFS mounts) */
> + if (umount2(mp->path, MNT_FORCE) == 0)
You have to execute things like /sbin/umount.<type> if you want to run your
code on systems with NFS or cluster filesystems.
> + mount_point_remove_and_free(mp, mount_point_list_head);
> + else {
> + log_debug("could not unmount %s: %m", mp->path);
> + failed++;
> + }
> + }
> +
> + return failed;
> +}
Karel
--
Karel Zak <kzak at redhat.com>
http://karelzak.blogspot.com
More information about the systemd-devel
mailing list