From 18c373e2686a9156a701ad440507172ec8bb13a3 Mon Sep 17 00:00:00 2001
From: wangyuhang <wangyuhang27@huawei.com>
Date: Fri, 7 Jul 2023 16:11:01 +0800
Subject: [PATCH] Add a new switch to control whether udev complies with the
 new SAT standards

Reason: Original revisions of the SAT (SCSI-ATA Translation) specification, 
 udev will identify devices starting with 70 and ending with 00 1d as ATA devices, 
 rather than scsi devices, which may have a change in wwn id and affect user usage.
 So Add a new switch to control whether udev complies with the new SAT standards

---
 src/shared/udev-util.c   | 16 ++++++++++++++--
 src/shared/udev-util.h   |  5 +++--
 src/udev/ata_id/ata_id.c | 20 +++++++++++++++++---
 src/udev/udevd.c         |  3 ++-
 4 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c
index f934fc1..2ff4a7c 100644
--- a/src/shared/udev-util.c
+++ b/src/shared/udev-util.c
@@ -38,9 +38,11 @@ int udev_parse_config_full(
                 usec_t *ret_exec_delay_usec,
                 usec_t *ret_event_timeout_usec,
                 ResolveNameTiming *ret_resolve_name_timing,
-                int *ret_timeout_signal) {
+                int *ret_timeout_signal,
+                bool *ret_ignore_newer_SAT) {
 
         _cleanup_free_ char *log_val = NULL, *children_max = NULL, *exec_delay = NULL, *event_timeout = NULL, *resolve_names = NULL, *timeout_signal = NULL;
+        _cleanup_free_ char *ignore_newer_SAT = NULL;
         int r;
 
         r = parse_env_file(NULL, "/etc/udev/udev.conf",
@@ -49,7 +51,8 @@ int udev_parse_config_full(
                            "exec_delay", &exec_delay,
                            "event_timeout", &event_timeout,
                            "resolve_names", &resolve_names,
-                           "timeout_signal", &timeout_signal);
+                           "timeout_signal", &timeout_signal,
+                           "ignore_newer_SAT", &ignore_newer_SAT);
         if (r == -ENOENT)
                 return 0;
         if (r < 0)
@@ -118,6 +121,15 @@ int udev_parse_config_full(
                         *ret_timeout_signal = r;
         }
 
+        if (ret_ignore_newer_SAT && ignore_newer_SAT) {
+                r = parse_boolean(ignore_newer_SAT);
+                if (r < 0)
+                        log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
+                                   "failed to parse ignore_newer_SAT=%s, ignoring.", ignore_newer_SAT);
+                else
+                    *ret_ignore_newer_SAT = r;
+        }
+
         return 0;
 }
 
diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h
index 276686d..9695c64 100644
--- a/src/shared/udev-util.h
+++ b/src/shared/udev-util.h
@@ -30,10 +30,11 @@ int udev_parse_config_full(
                 usec_t *ret_exec_delay_usec,
                 usec_t *ret_event_timeout_usec,
                 ResolveNameTiming *ret_resolve_name_timing,
-                int *ret_timeout_signal);
+                int *ret_timeout_signal,
+                bool *ret_ignore_newer_SAT);
 
 static inline int udev_parse_config(void) {
-        return udev_parse_config_full(NULL, NULL, NULL, NULL, NULL);
+        return udev_parse_config_full(NULL, NULL, NULL, NULL, NULL, NULL);
 }
 
 int device_wait_for_initialization(sd_device *device, const char *subsystem, usec_t deadline, sd_device **ret);
diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c
index d0c5217..2dbe1ef 100644
--- a/src/udev/ata_id/ata_id.c
+++ b/src/udev/ata_id/ata_id.c
@@ -28,9 +28,13 @@
 #include "log.h"
 #include "memory-util.h"
 #include "udev-util.h"
+#include "proc-cmdline.h"
+#include "string-util.h"
 
 #define COMMAND_TIMEOUT_MSEC (30 * 1000)
 
+static bool arg_ignore_newer_SAT = false;
+
 static int disk_scsi_inquiry_command(
                 int fd,
                 void *buf,
@@ -163,7 +167,7 @@ static int disk_identify_command(
         }
 
         if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c) &&
-                !(sense[0] == 0x70 && sense[12] == 0x00 && sense[13] == 0x1d)) {
+                (arg_ignore_newer_SAT || !(sense[0] == 0x70 && sense[12] == 0x00 && sense[13] == 0x1d))) {
                 errno = EIO;
                 return -1;
         }
@@ -413,13 +417,23 @@ int main(int argc, char *argv[]) {
                 { "help", no_argument, NULL, 'h' },
                 {}
         };
-        int peripheral_device_type = -1;
+        int r, peripheral_device_type = -1;
 
         log_set_target(LOG_TARGET_AUTO);
-        udev_parse_config();
+        udev_parse_config_full(NULL, NULL, NULL, NULL, NULL, &arg_ignore_newer_SAT);
         log_parse_environment();
         log_open();
 
+        /* When either ignore_newer_SAT in udev.conf or udev.ignore_newer_SAT in the kernel command line is true,
+         * set arg_ignore_newer_SAT to true and ignoring the new SAT standard
+         */
+        if (!arg_ignore_newer_SAT) {
+                r = proc_cmdline_get_bool("udev.ignore_newer_SAT", &arg_ignore_newer_SAT);
+                if (r < 0) {
+                        log_warning_errno(r, "Failed to parse udev.ignore_newer_SAT kernel command line argument, ignoring: %m");
+                }
+        }
+
         for (;;) {
                 int option;
 
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 405a593..e78a28a 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -2074,7 +2074,8 @@ int run_udevd(int argc, char *argv[]) {
 
         log_set_target(LOG_TARGET_AUTO);
         log_open();
-        udev_parse_config_full(&arg_children_max, &arg_exec_delay_usec, &arg_event_timeout_usec, &arg_resolve_name_timing, &arg_timeout_signal);
+        /* ignore_newer_SAT only valid in ata_id.c */
+        udev_parse_config_full(&arg_children_max, &arg_exec_delay_usec, &arg_event_timeout_usec, &arg_resolve_name_timing, &arg_timeout_signal, NULL);
         log_parse_environment();
         log_open(); /* Done again to update after reading configuration. */
 
-- 
2.33.0

