[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