Use dm-uuid for all crypt devices, contains device type and name now.
authorMilan Broz <gmazyland@gmail.com>
Tue, 8 Sep 2009 06:41:44 +0000 (06:41 +0000)
committerMilan Broz <gmazyland@gmail.com>
Tue, 8 Sep 2009 06:41:44 +0000 (06:41 +0000)
DM_UUID now contains prefix (CRYPT-), device type (LUKS1, PLAIN, TEMP),
UUID (if provided - LUKS) and device name.

Because e.g. snapshot of full LUKS device during activation must have different
name, DM-UUID is different too and we do not need --disable-uuid option.

DM-UUID is persistent during activation time.

* Revert (and solve different way): Replace not safe option --non-exclusive with --disable-uuid.

Signed-off-by: Milan Broz <mbroz@redhat.com>
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@105 36d66b0a-2a48-0410-832c-cd162a569da5

ChangeLog
lib/internal.h
lib/libcryptsetup.h
lib/libdevmapper.c
lib/setup.c
luks/keyencryption.c
man/cryptsetup.8
src/cryptsetup.c

index 6e4ccd2..abc5a5b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2009-09-08  Milan Broz  <mbroz@redhat.com>
+       * Use dm-uuid for all crypt devices, contains device type and name now.
+
 2009-09-02  Milan Broz  <mbroz@redhat.com>
        * Add luksSuspend (freeze device and wipe key) and luksResume (with provided passphrase).
 
@@ -20,7 +23,6 @@
        * Implement old API calls using new functions.
        * Remove old API code helper functions.
        * Add --master-key-file option for luksFormat and luksAddKey.
-       * Replace not safe option --non-exclusive with --disable-uuid.
 
 2009-08-17  Milan Broz  <mbroz@redhat.com>
        * Fix PBKDF2 speed calculation for large passhrases.
index 62c44f5..bf0e5fb 100644 (file)
@@ -81,8 +81,10 @@ int dm_query_device(const char *name,
                    int *key_size,
                    char **key,
                    int *read_only,
-                   int *suspended);
-int dm_create_device(const char *name, const char *device, const char *cipher, const char *uuid,
+                   int *suspended,
+                   char **uuid);
+int dm_create_device(const char *name, const char *device, const char *cipher,
+                    const char *type, const char *uuid,
                     uint64_t size, uint64_t skip, uint64_t offset,
                     size_t key_size, const char *key,
                     int read_only, int reload);
index 3c296a9..cdd30ec 100644 (file)
@@ -471,7 +471,7 @@ void crypt_set_debug_level(int level);
  * Provided only for backward compatibility.
  */
 
-struct interface_callbacks { 
+struct interface_callbacks {
     int (*yesDialog)(char *msg);
     void (*log)(int class, char *msg);
 };
index 61d0369..d359737 100644 (file)
@@ -2,8 +2,10 @@
 #include <dirent.h>
 #include <errno.h>
 #include <libdevmapper.h>
+#include <linux/dm-ioctl.h>
 #include <fcntl.h>
 #include <linux/fs.h>
+#include <uuid/uuid.h>
 
 #include "internal.h"
 #include "luks.h"
@@ -11,7 +13,6 @@
 #define DEVICE_DIR             "/dev"
 #define DM_UUID_PREFIX         "CRYPT-"
 #define DM_UUID_PREFIX_LEN     6
-#define DM_UUID_LEN            UUID_STRING_L
 #define DM_CRYPT_TARGET                "crypt"
 #define RETRY_COUNT            5
 
@@ -264,9 +265,42 @@ int dm_remove_device(const char *name, int force, uint64_t size)
        return r;
 }
 
+#define UUID_LEN 37 /* 36 + \0, libuuid ... */
+/*
+ * UUID has format: CRYPT-<devicetype>-[<uuid>-]<device name>
+ * CRYPT-PLAIN-name
+ * CRYPT-LUKS1-00000000000000000000000000000000-name
+ * CRYPT-TEMP-name
+ */
+static void dm_prepare_uuid(const char *name, const char *type, const char *uuid, char *buf, size_t buflen)
+{
+       char *ptr, uuid2[UUID_LEN] = {0};
+       uuid_t uu;
+       int i = 0;
+
+       /* Remove '-' chars */
+       if (uuid && !uuid_parse(uuid, uu)) {
+               for (ptr = uuid2, i = 0; i < UUID_LEN; i++)
+                       if (uuid[i] != '-') {
+                               *ptr = uuid[i];
+                               ptr++;
+                       }
+       }
+
+       i = snprintf(buf, buflen, DM_UUID_PREFIX "%s%s%s%s%s",
+               type ?: "", type ? "-" : "",
+               uuid2[0] ? uuid2 : "", uuid2[0] ? "-" : "",
+               name);
+
+       log_dbg("DM-UUID is %s", buf);
+       if (i >= buflen)
+               log_err(NULL, _("DM-UUID for device %s was truncated.\n"), name);
+}
+
 int dm_create_device(const char *name,
                     const char *device,
                     const char *cipher,
+                    const char *type,
                     const char *uuid,
                     uint64_t size,
                     uint64_t skip,
@@ -281,25 +315,35 @@ int dm_create_device(const char *name,
        struct dm_info dmi;
        char *params = NULL;
        char *error = NULL;
-       char dev_uuid[DM_UUID_PREFIX_LEN + DM_UUID_LEN + 1] = {0};
+       char dev_uuid[DM_UUID_LEN] = {0};
        int r = -EINVAL;
        uint32_t read_ahead = 0;
 
        params = get_params(device, skip, offset, cipher, key_size, key);
        if (!params)
                goto out_no_removal;
-       if (uuid) {
-               strncpy(dev_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN);
-               strncpy(dev_uuid + DM_UUID_PREFIX_LEN, uuid, DM_UUID_LEN);
-               dev_uuid[DM_UUID_PREFIX_LEN + DM_UUID_LEN] = '\0';
+
+       /* All devices must have DM_UUID, only resize on old device is exception */
+       if (reload) {
+               if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
+                       goto out_no_removal;
+
+               if (!dm_task_set_name(dmt, name))
+                       goto out_no_removal;
+       } else {
+               dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid));
+
+               if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
+                       goto out_no_removal;
+
+               if (!dm_task_set_name(dmt, name))
+                       goto out_no_removal;
+
+               if (!dm_task_set_uuid(dmt, dev_uuid))
+                       goto out_no_removal;
        }
 
-       if (!(dmt = dm_task_create(reload ? DM_DEVICE_RELOAD
-                                         : DM_DEVICE_CREATE)))
-               goto out_no_removal;
-       if (!dm_task_set_name(dmt, name))
-               goto out_no_removal;
+
        if (read_only && !dm_task_set_ro(dmt))
                goto out_no_removal;
        if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params))
@@ -311,9 +355,6 @@ int dm_create_device(const char *name,
                goto out_no_removal;
 #endif
 
-       if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
-               goto out_no_removal;
-
        if (!dm_task_run(dmt))
                goto out_no_removal;
 
@@ -412,12 +453,13 @@ int dm_query_device(const char *name,
                    int *key_size,
                    char **key,
                    int *read_only,
-                   int *suspended)
+                   int *suspended,
+                   char **uuid)
 {
        struct dm_task *dmt;
        struct dm_info dmi;
        uint64_t start, length, val64;
-       char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3];
+       char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3], *tmp_uuid;
        void *next = NULL;
        int i, r = -EINVAL;
 
@@ -508,6 +550,10 @@ int dm_query_device(const char *name,
        if (suspended)
                *suspended = dmi.suspended;
 
+       if (uuid && (tmp_uuid = (char*)dm_task_get_uuid(dmt)) &&
+           !strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
+               *uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
+
        r = (dmi.open_count > 0);
 out:
        if (dmt)
index 4854cc0..3fb8486 100644 (file)
@@ -372,7 +372,7 @@ static int create_device_helper(struct crypt_device *cd,
        if (!processed_key)
                return -ENOENT;
 
-       r = dm_create_device(name, cd->device, dm_cipher ?: cipher, uuid, size, skip, offset,
+       r = dm_create_device(name, cd->device, dm_cipher ?: cipher, cd->type, uuid, size, skip, offset,
                             key_size, processed_key, read_only, reload);
 
        free(dm_cipher);
@@ -402,9 +402,10 @@ static int open_from_hdr_and_mk(struct crypt_device *cd,
                     crypt_get_cipher_mode(cd)) < 0)
                r = -ENOMEM;
        else
-               r = dm_create_device(name, cd->device, cipher, no_uuid ? NULL : crypt_get_uuid(cd),
-                               size, 0, offset, mk->keyLength, mk->key,
-                               read_only, 0);
+               r = dm_create_device(name, cd->device, cipher, cd->type,
+                                    no_uuid ? NULL : crypt_get_uuid(cd),
+                                    size, 0, offset, mk->keyLength, mk->key,
+                                    read_only, 0);
        free(cipher);
        return r;
 }
@@ -490,16 +491,24 @@ static void key_from_file(struct crypt_device *cd, char *msg,
 }
 
 static int _crypt_init(struct crypt_device **cd,
+                      const char *type,
                       struct crypt_options *options,
                       int load, int need_dm)
 {
-       int r;
+       int init_by_name, r;
+
+       /* if it is plain device and mapping table is being reloaded
+       initialize it by name*/
+       init_by_name = (type && !strcmp(type, CRYPT_PLAIN) && load);
 
        /* Some of old API calls do not require DM in kernel,
           fake initialisation by initialise it with kernel_check disabled */
        if (!need_dm)
                (void)dm_init(NULL, 0);
-       r = crypt_init(cd, options->device);
+       if (init_by_name)
+               r = crypt_init_by_name(cd, options->name);
+       else
+               r = crypt_init(cd, options->device);
        if (!need_dm)
                dm_exit();
 
@@ -511,11 +520,20 @@ static int _crypt_init(struct crypt_device **cd,
 
        crypt_set_timeout(*cd, options->timeout);
        crypt_set_password_retry(*cd, options->tries);
-       crypt_set_iterarion_time(*cd, options->iteration_time);
+       crypt_set_iterarion_time(*cd, options->iteration_time ?: 1000);
        crypt_set_password_verify(*cd, options->flags & CRYPT_FLAG_VERIFY);
 
-       if (load)
-               r = crypt_load(*cd, CRYPT_LUKS1, NULL);
+       if (load && !init_by_name)
+               r = crypt_load(*cd, type, NULL);
+
+       if (type && !(*cd)->type) {
+               (*cd)->type = strdup(type);
+               if (!(*cd)->type)
+                       r = -ENOMEM;
+       }
+
+       if (r)
+               crypt_free(*cd);
 
        return r;
 }
@@ -554,7 +572,7 @@ int crypt_create_device(struct crypt_options *options)
        unsigned int keyLen;
        int r;
 
-       r = _crypt_init(&cd, options, 0, 1);
+       r = _crypt_init(&cd, CRYPT_PLAIN, options, 0, 1);
        if (r)
                return r;
 
@@ -582,7 +600,7 @@ int crypt_update_device(struct crypt_options *options)
        unsigned int keyLen;
        int r;
 
-       r = _crypt_init(&cd, options, 0, 1);
+       r = _crypt_init(&cd, CRYPT_PLAIN, options, 1, 1);
        if (r)
                return r;
 
@@ -606,30 +624,43 @@ int crypt_update_device(struct crypt_options *options)
 int crypt_resize_device(struct crypt_options *options)
 {
        struct crypt_device *cd = NULL;
-       char *device, *cipher, *key = NULL;
+       char *device = NULL, *cipher = NULL, *uuid = NULL, *key = NULL;
+       char *type = NULL;
        uint64_t size, skip, offset;
        int key_size, read_only, r;
 
        r = dm_query_device(options->name, &device, &size, &skip, &offset,
-                           &cipher, &key_size, &key, &read_only, NULL);
+                           &cipher, &key_size, &key, &read_only, NULL, &uuid);
        if (r < 0)
-               return r;
+               goto out;
 
-       r = _crypt_init(&cd, options, 0, 1);
+       /* Try to determine type of device from UUID */
+       if (uuid) {
+               if (!strncmp(uuid, CRYPT_PLAIN, strlen(CRYPT_PLAIN))) {
+                       type = CRYPT_PLAIN;
+                       free (uuid);
+                       uuid = NULL;
+               } else if (!strncmp(uuid, CRYPT_LUKS1, strlen(CRYPT_LUKS1)))
+                       type = CRYPT_LUKS1;
+       }
+
+       r = _crypt_init(&cd, type, options, 1, 1);
        if (r)
-               return r;
+               goto out;
 
        size = options->size;
        r = device_check_and_adjust(cd, device, &size, &offset, &read_only);
        if (r)
-               return r;
+               goto out;
 
-       r = dm_create_device(options->name, device, cipher, NULL, size, skip, offset,
+       r = dm_create_device(options->name, device, cipher, type,
+                            crypt_get_uuid(cd), size, skip, offset,
                             key_size, key, read_only, 1);
-
+out:
        safe_free(key);
        free(cipher);
        free(device);
+       free(uuid);
        crypt_free(cd);
        return r;
 }
@@ -645,7 +676,7 @@ int crypt_query_device(struct crypt_options *options)
 
        r = dm_query_device(options->name, (char **)&options->device, &options->size,
                            &options->skip, &options->offset, (char **)&options->cipher,
-                           &options->key_size, NULL, &read_only, NULL);
+                           &options->key_size, NULL, &read_only, NULL, NULL);
 
        if (r < 0)
                return r;
@@ -686,7 +717,7 @@ int crypt_luksFormat(struct crypt_options *options)
                return r;
        }
 
-       if ((r = _crypt_init(&cd, options, 0, 1)))
+       if ((r = _crypt_init(&cd, CRYPT_LUKS1, options, 0, 1)))
                return r;
 
        if (options->key_slot >= LUKS_NUMKEYS && options->key_slot != CRYPT_ANY_SLOT) {
@@ -728,7 +759,7 @@ int crypt_luksOpen(struct crypt_options *options)
        if (!options->name)
                return -EINVAL;
 
-       r = _crypt_init(&cd, options, 1, 1);
+       r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
        if (r)
                return r;
 
@@ -758,7 +789,7 @@ int crypt_luksKillSlot(struct crypt_options *options)
        struct crypt_device *cd = NULL;
        int r;
 
-       r = _crypt_init(&cd, options, 1, 1);
+       r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
        if (r)
                return r;
 
@@ -775,7 +806,7 @@ int crypt_luksRemoveKey(struct crypt_options *options)
        struct crypt_device *cd = NULL;
        int r;
 
-       r = _crypt_init(&cd, options, 1, 1);
+       r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
        if (r)
                return r;
 
@@ -794,7 +825,7 @@ int crypt_luksAddKey(struct crypt_options *options)
        struct crypt_device *cd = NULL;
        int r = -EINVAL;
 
-       r = _crypt_init(&cd, options, 1, 1);
+       r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
        if (r)
                return r;
 
@@ -817,7 +848,7 @@ int crypt_luksUUID(struct crypt_options *options)
        char *uuid;
        int r;
 
-       r = _crypt_init(&cd, options, 1, 0);
+       r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0);
        if (r)
                return r;
 
@@ -834,8 +865,9 @@ int crypt_isLuks(struct crypt_options *options)
        struct crypt_device *cd = NULL;
        int r;
 
-       r = _crypt_init(&cd, options, 1, 0);
-       crypt_free(cd);
+       r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0);
+       if (!r)
+               crypt_free(cd);
        return r;
 }
 
@@ -845,7 +877,7 @@ int crypt_luksDump(struct crypt_options *options)
        struct crypt_device *cd = NULL;
        int r;
 
-       r = _crypt_init(&cd, options, 1, 0);
+       r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0);
        if(r < 0)
                return r;
 
@@ -943,7 +975,7 @@ int crypt_init_by_name(struct crypt_device **cd, const char *name)
        }
 
        r = dm_query_device(name, &device, NULL, NULL, NULL,
-                           NULL, NULL, NULL, NULL, NULL);
+                           NULL, NULL, NULL, NULL, NULL, NULL);
        if (!r)
                r = crypt_init(cd, device);
 
@@ -1123,7 +1155,7 @@ int crypt_suspend(struct crypt_device *cd,
        }
 
        r = dm_query_device(name, NULL, NULL, NULL, NULL,
-                           NULL, NULL, NULL, NULL, &suspended);
+                           NULL, NULL, NULL, NULL, &suspended, NULL);
        if (r < 0)
                return r;
 
@@ -1157,7 +1189,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
        }
 
        r = dm_query_device(name, NULL, NULL, NULL, NULL,
-                           NULL, NULL, NULL, NULL, &suspended);
+                           NULL, NULL, NULL, NULL, &suspended, NULL);
        if (r < 0)
                return r;
 
@@ -1204,7 +1236,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
        }
 
        r = dm_query_device(name, NULL, NULL, NULL, NULL,
-                           NULL, NULL, NULL, NULL, &suspended);
+                           NULL, NULL, NULL, NULL, &suspended, NULL);
        if (r < 0)
                return r;
 
index f32729b..28b1a0d 100644 (file)
@@ -71,7 +71,7 @@ static int setup_mapping(const char *cipher, const char *name,
        size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
        cleaner_size = size;
 
-       return dm_create_device(name, device, cipher, NULL, size, 0, sector,
+       return dm_create_device(name, device, cipher, "TEMP", NULL, size, 0, sector,
                                keyLength, key, (mode == O_RDONLY), 0);
 }
 
index 8c9ac46..423df19 100644 (file)
@@ -146,9 +146,6 @@ This option is only relevant for \fIcreate\fR action.
 .B "\-\-readonly"
 set up a read-only mapping.
 .TP
-.B "\-\-disable-uuid"
-Activate device without UUID. Useful for \fIluksOpen\fR to activate cloned LUKS device or its snapshot.
-.TP
 .B "\-\-iter-time, \-i"
 The number of milliseconds to spend with PBKDF2 password processing. This option is only relevant to the LUKS operations as \fIluksFormat\fR or \fIluksAddKey\fR.
 .TP
index db51c14..dc337fc 100644 (file)
@@ -34,7 +34,7 @@ static int opt_version_mode = 0;
 static int opt_timeout = 0;
 static int opt_tries = 3;
 static int opt_align_payload = 0;
-static int opt_disable_uuid = 0;
+static int opt_non_exclusive = 0;
 
 static const char **action_argv;
 static int action_argc;
@@ -375,8 +375,8 @@ static int action_luksOpen(int arg)
 
        if (opt_readonly)
                options.flags |= CRYPT_FLAG_READONLY;
-       if (opt_disable_uuid) /* Abuse old flag */
-               options.flags |= CRYPT_FLAG_NON_EXCLUSIVE_ACCESS;
+       if (opt_non_exclusive)
+               log_err(_("Obsolete option --non-exclusive is ignored.\n"));
        return crypt_luksOpen(&options);
 }
 
@@ -637,7 +637,7 @@ int main(int argc, char **argv)
                { "timeout",           't',  POPT_ARG_INT,                                &opt_timeout,           0, N_("Timeout for interactive passphrase prompt (in seconds)"),          N_("secs") },
                { "tries",             'T',  POPT_ARG_INT,                                &opt_tries,             0, N_("How often the input of the passphrase canbe retried"),            NULL },
                { "align-payload",     '\0',  POPT_ARG_INT,                               &opt_align_payload,     0, N_("Align payload at <n> sector boundaries - for luksFormat"),         N_("SECTORS") },
-               { "disable-uuid",      '\0',  POPT_ARG_NONE,                              &opt_disable_uuid,      0, N_("Do not set UUID for device luksOpen."), NULL },
+               { "non-exclusive",     '\0',  POPT_ARG_NONE,                              &opt_non_exclusive,     0, N_("Allows non-exclusive access for luksOpen, WARNING see manpage."),        NULL },
                POPT_TABLEEND
        };
        poptContext popt_context;