]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- ignore subvol mount during search for filesystem
authorArvin Schnell <aschnell@suse.de>
Fri, 18 Sep 2015 12:15:12 +0000 (14:15 +0200)
committerArvin Schnell <aschnell@suse.de>
Fri, 18 Sep 2015 12:15:12 +0000 (14:15 +0200)
client/mksubvolume.cc
doc/mksubvolume.xml.in

index 4b2c6b92d8fc862c1b34c0f082afbefc71ef3d0e..57abfd6c69d257977a6765719f64e45331048f06 100644 (file)
@@ -201,6 +201,65 @@ do_set_nocow()
 }
 
 
+bool
+is_subvol_mount(const string& fs_options)
+{
+    list<string> tmp1;
+    boost::split(tmp1, fs_options, boost::is_any_of(","), boost::token_compress_on);
+    for (const string& tmp2 : tmp1)
+    {
+       if (boost::starts_with(tmp2, "subvol=") || boost::starts_with(tmp2, "subvolid="))
+           return true;
+    }
+
+    return false;
+}
+
+
+libmnt_fs*
+find_filesystem(MntTable& mnt_table)
+{
+    string tmp = target;
+
+    for (;;)
+    {
+       libmnt_fs* fs = mnt_table.find_target_up(tmp, MNT_ITER_FORWARD);
+       if (!fs)
+           throw runtime_error("filesystem not found");
+
+       string fs_device = mnt_fs_get_source(fs);
+       string fs_fstype = mnt_fs_get_fstype(fs);
+       string fs_target = mnt_fs_get_target(fs);
+       string fs_options = mnt_fs_get_options(fs);
+
+       if (verbose)
+       {
+           cout << "fs-device:" << fs_device << endl;
+           cout << "fs-fstype:" << fs_fstype << endl;
+           cout << "fs-target:" << fs_target << endl;
+           cout << "fs-options:" << fs_options << endl;
+       }
+
+       if (fs_fstype != "btrfs")
+           throw runtime_error("filesystem is not btrfs");
+
+       if (fs_target == target)
+           throw runtime_error("target exists in fstab");
+
+       if (!is_subvol_mount(fs_options))
+           return fs;
+
+       if (verbose)
+           cout << "ignoring subvol mount" << endl;
+
+       if (tmp == "/")
+           throw runtime_error("filesystem not found");
+
+       tmp = dirname(fs_target);
+    }
+}
+
+
 void
 doit()
 {
@@ -218,24 +277,9 @@ doit()
 
     // Find filesystem.
 
-    libmnt_fs* fs = mnt_table.find_target_up(target, MNT_ITER_FORWARD);
-    string fs_fstype = mnt_fs_get_fstype(fs);
+    libmnt_fs* fs = find_filesystem(mnt_table);
     string fs_target = mnt_fs_get_target(fs);
 
-    if (verbose)
-    {
-       cout << "fs-device:" << mnt_fs_get_source(fs) << endl;
-       cout << "fs-fstype:" << fs_fstype << endl;
-       cout << "fs-target:" << fs_target << endl;
-       cout << "fs-options:" << mnt_fs_get_options(fs) << endl;
-    }
-
-    if (fs_fstype != "btrfs")
-       throw runtime_error("filesystem is not btrfs");
-
-    if (fs_target == target)
-       throw runtime_error("target exists in fstab");
-
     // Get default subvolume of filesystem.
 
     int fd = open(fs_target.c_str(), O_RDONLY);
@@ -254,7 +298,9 @@ doit()
 
     // Determine subvol mount-option for tmp mount. The '@' is used on SLE.
 
-    string subvol_option = boost::starts_with(default_subvolume_name, "@/") ? "@" : "";
+    string subvol_option = "";
+    if (default_subvolume_name == "@" || boost::starts_with(default_subvolume_name, "@/"))
+       subvol_option = "@";
     if (verbose)
        cout << "subvol-option:" << subvol_option << endl;
 
@@ -307,7 +353,7 @@ void usage() __attribute__ ((__noreturn__));
 void
 usage()
 {
-    cerr << "usage: --target=target [--nocow] [--verbose]" << endl;
+    cerr << "usage: [--nocow] [--verbose] target" << endl;
     exit(EXIT_FAILURE);
 }
 
@@ -318,7 +364,6 @@ main(int argc, char** argv)
     setlocale(LC_ALL, "");
 
     const struct option options[] = {
-       { "target",             required_argument,      0,      't' },
        { "nocow",              no_argument,            0,      0 },
        { "verbose",            no_argument,            0,      'v' },
        { 0, 0, 0, 0 }
@@ -332,17 +377,17 @@ main(int argc, char** argv)
 
     GetOpts::parsed_opts::const_iterator opt;
 
-    if ((opt = opts.find("target")) != opts.end())
-        target = opt->second;
-    else
-       usage();
-
     if ((opt = opts.find("nocow")) != opts.end())
         set_nocow = true;
 
     if ((opt = opts.find("verbose")) != opts.end())
         verbose = true;
 
+    if (getopts.numArgs() != 1)
+       usage();
+
+    target = getopts.popArg();
+
     try
     {
        doit();
index e1706daebc8460866be46a69285de70ed38951ba..35cd6e94b0ba43c18b569acec7668565ea001d23 100644 (file)
   <refsynopsisdiv id='synopsis'>
     <cmdsynopsis>
       <command>mksubvolume</command>
-      <arg choice='req'>--target=<replaceable>path</replaceable></arg>
       <arg choice='opt'>--nocow</arg>
       <arg choice='opt'>--verbose</arg>
+      <arg choice='req'><replaceable>path</replaceable></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
 
   <refsect1 id='description'>
     <title>DESCRIPTION</title>
     <para>Mksubvolume is a command-line program to create a btrfs subvolume
-    including adding a fstab entry and mounting the subvolume.</para>
+    including adding a fstab entry and mounting the subvolume at
+    <replaceable>path</replaceable>.</para>
   </refsect1>
 
   <refsect1 id='global_options'>
     <title>OPTIONS</title>
     <variablelist>
-      <varlistentry>
-       <term><option>--target <replaceable>path</replaceable></option></term>
-       <listitem>
-         <para>Path of the subvolume to create.</para>
-       </listitem>
-      </varlistentry>
       <varlistentry>
        <term><option>--nocow</option></term>
        <listitem>