diff options
Diffstat (limited to 'src/nvme/util.c')
-rw-r--r-- | src/nvme/util.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/nvme/util.c b/src/nvme/util.c index ff5e0d8..c61dbe9 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -11,6 +11,8 @@ #include <string.h> #include <errno.h> +#include <sys/stat.h> +#include <fcntl.h> #include <sys/param.h> #include <sys/types.h> #include <arpa/inet.h> @@ -23,6 +25,11 @@ #include "util.h" #include "log.h" +/* The bionic libc implementation doesn't define LINE_MAX */ +#ifndef LINE_MAX +#define LINE_MAX 2048 +#endif + /* Source Code Control System, query version of binary with 'what' */ const char sccsid[] = "@(#)libnvme " GIT_VERSION; @@ -489,6 +496,22 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) return 0; } +int nvme_get_feature_length2(int fid, __u32 cdw11, enum nvme_data_tfr dir, + __u32 *len) +{ + switch (fid) { + case NVME_FEAT_FID_HOST_MEM_BUF: + if (dir == NVME_DATA_TFR_HOST_TO_CTRL) { + *len = 0; + break; + } + fallthrough; + default: + return nvme_get_feature_length(fid, cdw11, len); + } + return 0; +} + int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 *len) { @@ -812,3 +835,57 @@ const char *nvme_get_version(enum nvme_version type) return "n/a"; } } + +int nvme_uuid_to_string(unsigned char uuid[NVME_UUID_LEN], char *str) +{ + int n; + n = snprintf(str, NVME_UUID_LEN_STRING, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], + uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); + return n != NVME_UUID_LEN_STRING - 1 ? -EINVAL : 0; +} + +int nvme_uuid_from_string(const char *str, unsigned char uuid[NVME_UUID_LEN]) +{ + int n; + + n = sscanf(str, + "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-" + "%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", + &uuid[0], &uuid[1], &uuid[2], &uuid[3], &uuid[4], &uuid[5], + &uuid[6], &uuid[7], &uuid[8], &uuid[9], &uuid[10], &uuid[11], + &uuid[12], &uuid[13], &uuid[14], &uuid[15]); + return n != NVME_UUID_LEN ? -EINVAL : 0; + +} + +int nvme_uuid_random(unsigned char uuid[NVME_UUID_LEN]) +{ + int f; + ssize_t n; + + f = open("/dev/urandom", O_RDONLY); + if (f < 0) + return -errno; + n = read(f, uuid, NVME_UUID_LEN); + if (n < 0) { + close(f); + return -errno; + } else if (n != NVME_UUID_LEN) { + close(f); + return -EIO; + } + + /* + * See https://www.rfc-editor.org/rfc/rfc4122#section-4.4 + * Algorithms for Creating a UUID from Truly Random + * or Pseudo-Random Numbers + */ + uuid[6] = (uuid[6] & 0x0f) | 0x40; + uuid[8] = (uuid[8] & 0x3f) | 0x80; + + return 0; +} |